Queries to find the future closest date
Given an array arr[] consisting of N strings and an array Query[] consisting of Q queries. Each string in arrays arr[] and Query[] is of the form D/M/Y where D, M and Y denotes the date, month and year. For each query, the task is to print the next closest date from the given array arr[]. If no such date exists, print “-1”.
Examples:
Input: arr[]={“22/4/1233”, “1/3/633”, “23/5/56645”, “4/12/233”}, Q = 2,
Query[] = {“23/3/4345”, “12/3/2”}
Output:
23/5/56645
4/12/233
Explanation:
Query 1: The closest date after “23/3/4345” is “23/5/56645”.
Query 2: The closest date after “12/3/2” is “4/12/233”.Input: arr[]={“22/4/1233”, “4/12/233”, “1/3/633”, “23/5/56645”}, Q = 1,
Query[] = {“4/4/34234234”}
Output: -1
Naive Approach: The simplest approach for each query in the array Query[] is to traverse the array arr[] and for each date, check if it is greater than the current date or not and if it closest to it or not. After complete traversal of the array, print the closest date obtained. If no date is found, print -1.
Time Complexity: O(N*Q)
Auxiliary Space: O(1)
Efficient Approach: The idea is to sort the given array arr[] using a comparator function. Then use a Binary Search to find the future date closest to each date in Query[]. Follow the steps below to solve the problem:
- Sort the array of dates arr[] by comparing the year first, then the month followed by the day.
- After sorting the array in the above step, for each query, find the closest date using binary search to compare two dates use the comparator function.
- If no valid date is found, then print “-1”.
- Otherwise, print the closest date found.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; vector<string> tokenize(string s, string del) { vector<string> res; int start, end = -1 * del.size(); do { start = end + del.size(); end = s.find(del, start); res.push_back(s.substr(start, end - start)); } while (end != -1); return res; } // Comparator function to compare // the two dates int comp(string s, string t) { // Split the dates strings // when a "/" found vector<string> ss = tokenize(s, "/" ); vector<string> tt = tokenize(t, "/" ); int date1[3]; int date2[3]; // Store the dates in form // of arrays for ( int i = 0; i < 3; i++) { date1[i] = stoi(ss[i]); date2[i] = stoi(tt[i]); } // If years are not same if (date1[2] != date2[2]) { return date1[2] - date2[2]; } // If months are not same else if (date1[1] != date2[1]) { return date1[1] - date2[1]; } // If days are not same else if (date1[0] != date2[0]) { return date1[0] - date2[0]; } // If two date is same return 0; } // Function to print the next // closest date string nextClosestDate(vector<string> arr, string q) { // Sort date array sort(arr.begin(), arr.end(), comp); // Perform the Binary search // to answer the queries int l = 0, r = arr.size() - 1; int ind = -1; // Iterate until l <= r while (l <= r) { // Find mid m int m = (l + r) / 2; // Comparator function call int c = comp(q, arr[m]); // If comp function return 0 // next closest date is found if (c == 0) { ind = m; break ; } // If comp function return // less than 0, search in // the left half else if (c < 0) { r = m - 1; ind = m; } // If comp function return // greater than 0, search // in the right half else { l = m + 1; } } // Return the result if (ind == -1) { return "-1" ; } else { return arr[ind]; } } void performQueries(vector<string> arr, vector<string> Q) { // Traverse the queries of date for ( int i = 0; i < Q.size(); i++) { // Function Call cout << nextClosestDate(arr, Q[i]) << endl; } } // Driver Code int main() { // Given array of dates vector<string> arr = { "22/4/1233" , "1/3/633" , "23/5/56645" , "4/12/233" }; // Given Queries vector<string> Q = { "23/3/4345" , "4/4/34234234" , "12/3/2" }; // Function Call performQueries(arr, Q); } // This code is contributed by phasing17. |
Java
// Java program for the above approach import java.awt.*; import java.io.*; import java.util.*; class GFG { // Comparator function to compare // the two dates public static int comp(String s, String t) { // Split the dates strings // when a "/" found String[] ss = s.split( "/" ); String[] tt = t.split( "/" ); int date1[] = new int [ 3 ]; int date2[] = new int [ 3 ]; // Store the dates in form // of arrays for ( int i = 0 ; i < 3 ; i++) { date1[i] = Integer.parseInt(ss[i]); date2[i] = Integer.parseInt(tt[i]); } // If years are not same if (date1[ 2 ] != date2[ 2 ]) { return date1[ 2 ] - date2[ 2 ]; } // If months are not same else if (date1[ 1 ] != date2[ 1 ]) { return date1[ 1 ] - date2[ 1 ]; } // If days are not same else if (date1[ 0 ] != date2[ 0 ]) { return date1[ 0 ] - date2[ 0 ]; } // If two date is same return 0 ; } // Function to print the next // closest date public static String nextClosestDate(String arr[], String q) { // Sort date array Arrays.sort(arr, new Comparator<String>() { @Override public int compare(String o1, String o2) { return comp(o1, o2); } }); // Perform the Binary search // to answer the queries int l = 0 , r = arr.length - 1 ; int ind = - 1 ; // Iterate until l <= r while (l <= r) { // Find mid m int m = (l + r) / 2 ; // Comparator function call int c = comp(q, arr[m]); // If comp function return 0 // next closest date is found if (c == 0 ) { ind = m; break ; } // If comp function return // less than 0, search in // the left half else if (c < 0 ) { r = m - 1 ; ind = m; } // If comp function return // greater than 0, search // in the right half else { l = m + 1 ; } } // Return the result if (ind == - 1 ) { return "-1" ; } else { return arr[ind]; } } public static void performQueries(String[] arr, String[] Q) { // Traverse the queries of date for ( int i = 0 ; i < Q.length; i++) { // Function Call System.out.println( nextClosestDate(arr, Q[i])); } } // Driver Code public static void main(String[] args) { // Given array of dates String arr[] = { "22/4/1233" , "1/3/633" , "23/5/56645" , "4/12/233" }; // Given Queries String Q[] = { "23/3/4345" , "4/4/34234234" , "12/3/2" }; // Function Call performQueries(arr, Q); } } |
Python3
# Python3 program for the above approach import functools # Comparator function to compare # the two dates def comp(s, t): # Split the dates strings # when a "/" found ss = s.split( "/" ); tt = t.split( "/" ); # Store the dates in form # of arrays date1 = [ int (ele) for ele in ss] date2 = [ int (ele) for ele in tt] # If years are not same if (date1[ 2 ] ! = date2[ 2 ]): return date1[ 2 ] - date2[ 2 ]; # If months are not same elif (date1[ 1 ] ! = date2[ 1 ]) : return date1[ 1 ] - date2[ 1 ]; # If days are not same elif (date1[ 0 ] ! = date2[ 0 ]) : return date1[ 0 ] - date2[ 0 ]; # If two date is same return 0 ; # Function to print the next # closest date def nextClosestDate(arr, q): # Sort date array arr.sort(key = functools.cmp_to_key(comp)) # Perform the Binary search # to answer the queries l = 0 r = len (arr) - 1 ind = - 1 ; # Iterate until l <= r while (l < = r) : # Find mid m m = int ((l + r) / 2 ); # Comparator function call c = comp(q, arr[m]); # If comp function return 0 # next closest date is found if (c = = 0 ) : ind = m; break ; # If comp function return # less than 0, search in # the left half elif (c < 0 ) : r = m - 1 ; ind = m; # If comp function return # greater than 0, search # in the right half else : l = m + 1 ; # Return the result if (ind = = - 1 ) : return "-1" ; else : return arr[ind]; def performQueries(arr, Q): # Traverse the queries of date for i in range ( len (Q)): # Function Call print (nextClosestDate(arr, Q[i])); # Driver Code # Given array of dates arr = [ "22/4/1233" , "1/3/633" , "23/5/56645" , "4/12/233" ]; # Given Queries Q = [ "23/3/4345" , "4/4/34234234" , "12/3/2" ]; # Function Call performQueries(arr, Q); # This code is contributed by phasing17. |
C#
// C# program for the above approach using System; using System.Collections.Generic; class GFG { // Comparator function to compare // the two dates public static int comp( string s, string t) { // Split the dates strings // when a "/" found string [] ss = s.Split( "/" ); string [] tt = t.Split( "/" ); int [] date1 = new int [3]; int [] date2 = new int [3]; // Store the dates in form // of arrays for ( int i = 0; i < 3; i++) { date1[i] = Convert.ToInt32(ss[i]); date2[i] = Convert.ToInt32(tt[i]); } // If years are not same if (date1[2] != date2[2]) { return date1[2] - date2[2]; } // If months are not same else if (date1[1] != date2[1]) { return date1[1] - date2[1]; } // If days are not same else if (date1[0] != date2[0]) { return date1[0] - date2[0]; } // If two date is same return 0; } // Function to print the next // closest date public static string nextClosestDate( string [] arr, string q) { // Sort date array Array.Sort(arr, comp); // Perform the Binary search // to answer the queries int l = 0, r = arr.Length - 1; int ind = -1; // Iterate until l <= r while (l <= r) { // Find mid m int m = (l + r) / 2; // Comparator function call int c = comp(q, arr[m]); // If comp function return 0 // next closest date is found if (c == 0) { ind = m; break ; } // If comp function return // less than 0, search in // the left half else if (c < 0) { r = m - 1; ind = m; } // If comp function return // greater than 0, search // in the right half else { l = m + 1; } } // Return the result if (ind == -1) { return "-1" ; } else { return arr[ind]; } } public static void performQueries( string [] arr, string [] Q) { // Traverse the queries of date for ( int i = 0; i < Q.Length; i++) { // Function Call Console.WriteLine( nextClosestDate(arr, Q[i])); } } // Driver Code public static void Main( string [] args) { // Given array of dates string [] arr = { "22/4/1233" , "1/3/633" , "23/5/56645" , "4/12/233" }; // Given Queries string [] Q = { "23/3/4345" , "4/4/34234234" , "12/3/2" }; // Function Call performQueries(arr, Q); } } // This code is contributed by phasing17. |
Javascript
// JavaScript program for the above approach // Comparator function to compare // the two dates function comp(s, t) { // Split the dates strings // when a "/" found let ss = s.split( "/" ); let tt = t.split( "/" ); let date1 = new Array(3); let date2 = new Array(3); // Store the dates in form // of arrays for ( var i = 0; i < 3; i++) { date1[i] = parseInt(ss[i]); date2[i] = parseInt(tt[i]); } // If years are not same if (date1[2] != date2[2]) { return date1[2] - date2[2]; } // If months are not same else if (date1[1] != date2[1]) { return date1[1] - date2[1]; } // If days are not same else if (date1[0] != date2[0]) { return date1[0] - date2[0]; } // If two date is same return 0; } // Function to print the next // closest date function nextClosestDate(arr, q) { // Sort date array arr.sort( function (a, b){ return comp(a, b) }) // Perform the Binary search // to answer the queries let l = 0, r = arr.length - 1; let ind = -1; // Iterate until l <= r while (l <= r) { // Find mid m let m = Math.floor((l + r) / 2); // Comparator function call let c = comp(q, arr[m]); // If comp function return 0 // next closest date is found if (c == 0) { ind = m; break ; } // If comp function return // less than 0, search in // the left half else if (c < 0) { r = m - 1; ind = m; } // If comp function return // greater than 0, search // in the right half else { l = m + 1; } } // Return the result if (ind == -1) { return "-1" ; } else { return arr[ind]; } } function performQueries(arr, Q) { // Traverse the queries of date for ( var i = 0; i < Q.length; i++) { // Function Call console.log(nextClosestDate(arr, Q[i])); } } // Driver Code // Given array of dates let arr = [ "22/4/1233" , "1/3/633" , "23/5/56645" , "4/12/233" ]; // Given Queries let Q = [ "23/3/4345" , "4/4/34234234" , "12/3/2" ]; // Function Call performQueries(arr, Q); // This code is contributed by phasing17. |
23/5/56645 -1 4/12/233
Time Complexity: O((N*log N) + (Q*log N))
Auxiliary Space: O(1)
Please Login to comment...