下一个更大的数
有一串字符组成的数组,这些字符全都是0-9之间的,比如2,1,7,8,9,求用这些字符组成的比21789大的第一个数。
也就是21798了。
假设这个数据很长,那么我们怎么做呢,用暴力法估计电脑要罢工了。
首先肯定是局部性原理了,下一个更大的数不能从前往后看,只能从后往前看,比如1234535324534245324567,下一个比它更大的数是1234535324534245324576,黑色加粗的部分是没有变化的。
那么我们先分析一下数据。
假如数据是153647,由这几个数字组成的最大数是765431,最小是134567。
假如把数据看成升降的,如图:
我们经过一次次找下一个更大的,一直找下去,最后图就成这样了
也就是说寻找的过程其实是把这个图变成一个斜向下的过程。每次变化的地方应该就是拐弯的地方了,拐弯无非有两种情况,第一种“√”第二种"^"。
第一种情况假如后面的两个数据是升序的,比如这个…………148,那么直接后两个交换位置就Ok,结果是…………184
第二种情况,假设数据是是这样的,……14862,后面是下降的该怎么办呢?
我们就顺着尾巴反向找,找第一个呈下降的
首先6比2大,上升的,8比6大,上升的。4不比8大,下降的,找到这个数了,就是4。
接下来我们再从尾巴找第一个比4大的数。然后就找到6了。
(为什么要找第一个比他大的数,首先,前面的数没变,后面我们只需要看会变化的这几个数就好,4862,抛开4不看,862这3个数你还能找到比它还大的?没有,所以必须动高位了,然后我们就必须在8,6,2中找第一个比4大的,如果你找了个2,2***再怎么也不会比4***大,)
交换一下4,6这时候数就是……16842了,但是我们应该知道下一个数应该是16248啊,
8 4 2 是降序的,我们需要的是一个升序的。把尾巴反过来就是了。
综合起来:我们就是要找第一个下降的,然后让他跟后面第一个比它大的数交换,并把后面的数据变成上升排列的。
具体代码为:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(www.whfyyl.com);
String str = input.nextLine();
char [] Arr=str.toCharArray();
int len=Arr.length;
char temp=' ';
int tag=0;
for(int i=len-1;i>-1;i-- ){
if(i==0){
System.out.println("已经是最大的了");
tag=-1;
break;
}
if(Arr[i-1]
temp=Arr[i-1];
tag=i-1;
break;
}
}
if(tag!=-1) {
for(int i=len-1;i>0;i-- )
if(Arr[i]>temp)
{
char temp1;
temp1=Arr[i];
Arr[i]=Arr[tag];
Arr[tag]=temp1;
break;
}
Arrays.sort(Arr, tag+1, len);
System.out.println(Arr);
}
}
}
如果感觉哪里有问题,我没有考虑到的欢迎留言指正。