下一个更大的数

有一串字符组成的数组,这些字符全都是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(System.in);
       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]<Arr[i]){
        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);      
       }        
  }
}

如果感觉哪里有问题,我没有考虑到的欢迎留言指正。


猜你喜欢

转载自blog.csdn.net/mad_sword/article/details/79828730