要求的时间需要晚于当前时间且和当前时间最近。时间串里一共四个数字字符,做全排列即可,使用到回溯算法。把时间串里的“:”剔除后,做回溯爆搜,每取4个字符就判断一次:1.作为时间串是否合法;2.如果合法,反应到最终结果中去;
特殊处理1:当以输入时间串得不到更大的时间时,说明比当前时间更晚的是第二天的时间,又要求这个时间离当前时间最近,所以直接取能得到的最小时间即可。
特殊处理2:当输入“00:00”,“11:11”,“22:22”这些四个位置都相同的时间串时,答案是其本身,含义:第二天的同一时刻。
import java.util.*;
public class Main{
public static List<Character> path=new ArrayList<>();
public static int base,min=Integer.MAX_VALUE,diff=Integer.MAX_VALUE;
public static String ans="",original,minStr="";
public static void main(String[] args){
Scanner in=new Scanner(System.in);
String s=in.nextLine();
String[] a=s.split(":");
List<Character> list=new ArrayList<>();
original=a[0]+a[1];
char c=original.charAt(0);
int flag=0;
list.add(c);
for(int i=1;i<4;i++){
if(original.charAt(i)!=c){
flag=1;
}
list.add(original.charAt(i));
}
if(flag==0){
System.out.println(s);
return;
}
base=toMinutes(original);
dfs(list);
if(ans.length()==0){
ans=minStr;
}
ans=ans.substring(0,2)+":"+ans.substring(2,4);
System.out.println(ans);
}
public static void dfs(List<Character> list){
if(path.size()==4){
String s="";
for(char ch:path){
s+=ch;
}
if(!s.equals(original)&&check(s)){
int v=toMinutes(s),d=Math.abs(v-base);
// 维护一个最小值,当“没有大于base”发生时,作为最后的值
if(v<min){
min=v;
minStr=s;
}
if(v>base&&d<diff){
ans=s;
diff=d;
}
}
return;
}
for(int i=0;i<4;i++){
path.add(list.get(i));
dfs(list);
path.remove(path.size()-1);
}
}
public static int toMinutes(String s){
int h=Integer.parseInt(s.substring(0,2)),m=Integer.parseInt(s.substring(2,4));
return h*60+m;
}
public static boolean check(String s){
int h=Integer.parseInt(s.substring(0,2)),m=Integer.parseInt(s.substring(2,4));
return h>=0&&h<=23&&m>=0&&m<=59;
}
}