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++ 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 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 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# 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 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)