Given a date in the format dd mm yyyy, rearrange its digits to form a valid date that is greater than the given date. The new date must:
- Use exactly the same digits as the original date.
- Use each digit exactly once.
- Be the smallest (nearest) valid date greater than the given date.
- If no such date exists, return -1.
Note: Assume that every month has 30 days. Therefore, a valid date must have the day in the range 01 to 30 and the month in the range 01 to 12.
Examples:
Input: date = "12 02 2014"
Output: date = "21 02 2014"
Explanation: The digits of the given date are 1, 2, 0, 2, 2, 0, 1, 4. Rearranging these digits forms 21 02 2014, which is a valid date and the smallest date greater than the given date.Input: date = "09 05 1998"
Output: date = "05 09 1998"
Explanation: The digits of the given date are 0, 9, 0, 5, 1, 9, 9, 8. Rearranging these digits forms 05 09 1998, which is a valid date and the nearest date greater than the given date.
Generate All Unique Permutations - O(k) Time and O(1) Space
The idea is to generate all unique permutations of eight digits. For every valid date greater than the given date, keep track of the smallest one.
Let us understand with an example:
Input: date = "12 02 2014"
- Extract the digits from "12 02 2014" and sort them as [0, 0, 1, 1, 2, 2, 2, 4].
- Generate every unique permutation of these digits and form the corresponding day, month, and year.
- Ignore permutations that do not form a valid date (day not in 01–30, month not in 01–12, or year less than 1000).
- Among the valid dates greater than 12 02 2014, keep updating the answer whenever a smaller valid date is found.
- After checking all permutations, the nearest valid greater date obtained is "21 02 2014", which is returned.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
string nextDate(string &date)
{
// Extract and sort all digits of the given date.
vector<int> digits;
for (char c : date)
{
if (isdigit(c))
digits.push_back(c - '0');
}
sort(digits.begin(), digits.end());
int currDay = stoi(date.substr(0, 2));
int currMonth = stoi(date.substr(3, 2));
int currYear = stoi(date.substr(6, 4));
int currDate = currYear * 10000 + currMonth * 100 + currDay;
int bestDate = INT_MAX;
string ans = "-1";
// Check every distinct arrangement of the digits.
do
{
int day = digits[0] * 10 + digits[1];
int month = digits[2] * 10 + digits[3];
int year = digits[4] * 1000 + digits[5] * 100 + digits[6] * 10 + digits[7];
// Ignore invalid dates.
if (day < 1 || day > 30 || month < 1 || month > 12 || year < 1000)
continue;
int newDate = year * 10000 + month * 100 + day;
// Keep the nearest valid date greater than the original.
if (newDate > currDate && newDate < bestDate)
{
bestDate = newDate;
string res;
if (day < 10)
res += '0';
res += to_string(day);
res += " ";
if (month < 10)
res += '0';
res += to_string(month);
res += " ";
string yr = to_string(year);
while (yr.size() < 4)
yr = "0" + yr;
res += yr;
ans = res;
}
} while (next_permutation(digits.begin(), digits.end()));
return ans;
}
int main()
{
string date = "12 02 2014";
cout << "\"" << nextDate(date) << "\"";
return 0;
}
import java.util.*;
public class GFG {
static String nextDate(String date)
{
// Extract and sort all digits of the given date.
int[] digits = new int[8];
int idx = 0;
for (char c : date.toCharArray()) {
if (Character.isDigit(c))
digits[idx++] = c - '0';
}
Arrays.sort(digits);
int currDay
= Integer.parseInt(date.substring(0, 2));
int currMonth
= Integer.parseInt(date.substring(3, 5));
int currYear
= Integer.parseInt(date.substring(6, 10));
int currDate
= currYear * 10000 + currMonth * 100 + currDay;
int bestDate = Integer.MAX_VALUE;
String ans = "-1";
// Check every distinct arrangement of the digits.
do {
int day = digits[0] * 10 + digits[1];
int month = digits[2] * 10 + digits[3];
int year = digits[4] * 1000 + digits[5] * 100
+ digits[6] * 10 + digits[7];
// Ignore invalid dates.
if (day < 1 || day > 30 || month < 1
|| month > 12 || year < 1000)
continue;
int newDate = year * 10000 + month * 100 + day;
// Keep the nearest valid date greater than the
// original.
if (newDate > currDate && newDate < bestDate) {
bestDate = newDate;
StringBuilder res = new StringBuilder();
if (day < 10)
res.append('0');
res.append(day);
res.append(" ");
if (month < 10)
res.append('0');
res.append(month);
res.append(" ");
String yr = Integer.toString(year);
while (yr.length() < 4)
yr = "0" + yr;
res.append(yr);
ans = res.toString();
}
} while (nextPermutation(digits));
return ans;
}
static boolean nextPermutation(int[] arr)
{
int i = arr.length - 2;
while (i >= 0 && arr[i] >= arr[i + 1])
i--;
if (i < 0)
return false;
int j = arr.length - 1;
while (arr[j] <= arr[i])
j--;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
int l = i + 1, r = arr.length - 1;
while (l < r) {
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
l++;
r--;
}
return true;
}
public static void main(String[] args)
{
String date = "12 02 2014";
System.out.print("\"" + nextDate(date) + "\"");
}
}
# Function to find the next date
from itertools import permutations
def nextDate(date):
# Extract and sort all digits of the given date.
digits = [int(c) for c in date if c.isdigit()]
digits.sort()
currDay = int(date[:2])
currMonth = int(date[3:5])
currYear = int(date[6:])
currDate = currYear * 10000 + currMonth * 100 + currDay
bestDate = float('inf')
ans = '-1'
# Check every distinct arrangement of the digits.
for p in permutations(digits):
day = p[0] * 10 + p[1]
month = p[2] * 10 + p[3]
year = p[4] * 1000 + p[5] * 100 + p[6] * 10 + p[7]
# Ignore invalid dates.
if day < 1 or day > 30 or month < 1 or month > 12 or year < 1000:
continue
newDate = year * 10000 + month * 100 + day
# Keep the nearest valid date greater than the original.
if newDate > currDate and newDate < bestDate:
bestDate = newDate
res = ''
if day < 10:
res += '0'
res += str(day)
res += ' '
if month < 10:
res += '0'
res += str(month)
res += ' '
yr = str(year)
while len(yr) < 4:
yr = '0' + yr
res += yr
ans = res
return ans
if __name__ == '__main__':
date = '12 02 2014'
print(f'"{nextDate(date)}"')
using System;
class GFG {
static string nextDate(string date)
{
// Extract and sort all digits of the given date.
int[] digits = new int[8];
int idx = 0;
foreach(char c in date)
{
if (char.IsDigit(c))
digits[idx++] = c - '0';
}
Array.Sort(digits);
int currDay = int.Parse(date.Substring(0, 2));
int currMonth = int.Parse(date.Substring(3, 2));
int currYear = int.Parse(date.Substring(6, 4));
int currDate
= currYear * 10000 + currMonth * 100 + currDay;
int bestDate = int.MaxValue;
string ans = "-1";
// Check every distinct arrangement of the digits.
do {
int day = digits[0] * 10 + digits[1];
int month = digits[2] * 10 + digits[3];
int year = digits[4] * 1000 + digits[5] * 100
+ digits[6] * 10 + digits[7];
// Ignore invalid dates.
if (day < 1 || day > 30 || month < 1
|| month > 12 || year < 1000)
continue;
int newDate = year * 10000 + month * 100 + day;
// Keep the nearest valid date greater than the
// original.
if (newDate > currDate && newDate < bestDate) {
bestDate = newDate;
string res = "";
if (day < 10)
res += "0";
res += day.ToString();
res += " ";
if (month < 10)
res += "0";
res += month.ToString();
res += " ";
string yr = year.ToString();
while (yr.Length < 4)
yr = "0" + yr;
res += yr;
ans = res;
}
} while (NextPermutation(digits));
return ans;
}
static bool NextPermutation(int[] arr)
{
int i = arr.Length - 2;
while (i >= 0 && arr[i] >= arr[i + 1])
i--;
if (i < 0)
return false;
int j = arr.Length - 1;
while (arr[j] <= arr[i])
j--;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
int l = i + 1, r = arr.Length - 1;
while (l < r) {
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
l++;
r--;
}
return true;
}
static void Main()
{
string date = "12 02 2014";
Console.Write("\"" + nextDate(date) + "\"");
}
}
// Extract and sort all digits of the given date.
function nextDate(date)
{
let digits = [];
for (let c of date) {
if (c >= "0" && c <= "9")
digits.push(Number(c));
}
digits.sort((a, b) => a - b);
let currDay = parseInt(date.substring(0, 2));
let currMonth = parseInt(date.substring(3, 5));
let currYear = parseInt(date.substring(6, 10));
let currDate
= currYear * 10000 + currMonth * 100 + currDay;
let bestDate = Number.MAX_SAFE_INTEGER;
let ans = "-1";
// Check every distinct arrangement of the digits.
do {
let day = digits[0] * 10 + digits[1];
let month = digits[2] * 10 + digits[3];
let year = digits[4] * 1000 + digits[5] * 100
+ digits[6] * 10 + digits[7];
// Ignore invalid dates.
if (day < 1 || day > 30 || month < 1 || month > 12
|| year < 1000)
continue;
let newDate = year * 10000 + month * 100 + day;
// Keep the nearest valid date greater than the
// original.
if (newDate > currDate && newDate < bestDate) {
bestDate = newDate;
let res = "";
if (day < 10)
res += "0";
res += day;
res += " ";
if (month < 10)
res += "0";
res += month;
res += " ";
let yr = year.toString();
while (yr.length < 4)
yr = "0" + yr;
res += yr;
ans = res;
}
} while (nextPermutation(digits));
return ans;
}
function nextPermutation(arr)
{
let i = arr.length - 2;
while (i >= 0 && arr[i] >= arr[i + 1])
i--;
if (i < 0)
return false;
let j = arr.length - 1;
while (arr[j] <= arr[i])
j--;
[arr[i], arr[j]] = [ arr[j], arr[i] ];
let l = i + 1, r = arr.length - 1;
while (l < r) {
[arr[l], arr[r]] = [ arr[r], arr[l] ];
l++;
r--;
}
return true;
}
// Driver Code
let date = "12 02 2014";
console.log("\"" + nextDate(date) + "\"");
Output
"21 02 2014"
Time Complexity: O(k), where k is the total number of distinct permutations of the 8 digits.
Space Complexity: O(1), since only a fixed number of variables and an array of 8 digits are used. The input size is constant.