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實現

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