31. 下一个排列

  • 题目详述

31. 下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,31,3,2
3,2,11,2,3
1,1,51,5,1

 

二.自我探寻(较慢21ms,网络学习过程10ms)

思路:举例  

(1)13156-》13165

(2)13152-》13215

(3)24321-》31224

从倒数第二位开始向前

若后面存在比它大的数 在这些比它大的数中挑个最小的与之交换 然后对后面的数进行升序排列

  1. 从5开始,6比5大,交换变成13165,对5进行升序排列仍是13156
  2. 从5开始,没有比5大的,再看倒数第三位1 ,5和2都比1大,2比较小 交换 变成 13251 对倒数第三位后面的数进行升序排列 13215
  3. 从2(倒数第二位的)开始,后面没有比它大的

到3,后面没有比它大的

到4,后面没有比它大的

到2(第一位的),比他大的有 4 3 选择较小的3,变成34221

对第一位后面的进行排序,变成31224

代码:

class Solution {

    public void nextPermutation(int[] nums) {

            if(nums.length==1)

                return;

            int minx=nums.length-1;

           int maxx=nums.length-1;

           for(int q=nums.length-2;q>=0;q--)

           {

             if(nums[q]>=nums[maxx])

             {

                    maxx=q;

                    if(q==0)

                {

                   sort(0, nums.length-1, nums);

                }

                continue;

             }

             else if(nums[q]<nums[minx])

             {

                swap(q,minx,nums);

                sort(q+1,nums.length-1,nums);

                break;

             }

             else {

                swap(q,search(q,nums) , nums);

                sort(q+1, nums.length-1, nums);

                break;

            }

           }

    }

     public static void swap(int i,int j,int[] nums)

    {

       int s=nums[i];

       nums[i]=nums[j];

       nums[j]=s;

    }

     public static void sort(int i,int j,int[] nums)/**从第i位开始快排**/

    {

      int m=i;

       int n=j;

       if(m>=n)

       {

          return;

       }

       while(m<n)

       {

          while(m<n&&nums[n]>=nums[i])

           {

              n--;

           }

           while(m<n&&nums[m]<=nums[i])

           {

              m++;

           }

           if(m<n)

           {

              swap(m,n,nums);

           }

          

         }

       swap(i, n, nums);

       sort(n+1,j, nums);

       sort(i,n-1, nums);

    }

     public static int search(int q,int[] nums)/**返回比它大的最小的数的下标,t是传入的数的座标*/

    {

     

       int min=Integer.MAX_VALUE;

       int minx=0;

       for(int f=q+1;f<nums.length;f++)

       {

        

          if(nums[f]-nums[q]<min&&nums[f]-nums[q]>0)

          {

             min=nums[f]-nums[q];

             minx=f;

          }

       }

       return minx;

    }

}

评价:


 

  • 网络学习过程

思路:(1)13156-》13165

(2)13152-》13215

(3)24321-》31224

观察交换位后面 的数组 1525234321

仔细思考后会发现从后往前降序排列断掉的一位正是 交换位

搜寻大的时候可以用二分法(代码中没用)

最后仍是降序数组 直接翻转 为升序数组

代码:public class Solution {

    public void nextPermutation(int[] nums) {

        int i = nums.length - 2;

        while (i >= 0 && nums[i + 1] <= nums[i]) {

            i--;

        }

        if (i >= 0) {

            int j = nums.length - 1;

            while (j >= 0 && nums[j] <= nums[i]) {

                j--;

            }

            swap(nums, i, j);

        }

        reverse(nums, i + 1);

    }

 

    private void reverse(int[] nums, int start) {

        int i = start, j = nums.length - 1;

        while (i < j) {

            swap(nums, i, j);

            i++;

            j--;

        }

    }

 

    private void swap(int[] nums, int i, int j) {

        int temp = nums[i];

        nums[i] = nums[j];

        nums[j] = temp;

    }

}

评价:10ms

 

 

四.Python实现

 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章