leetcode31-下一個排列

leetcode31-下一個排列

實現獲取下一個排列的函數,算法需要將給定數字序列重新排列成字典序中下一個更大的排列。

如果不存在下一個更大的排列,則將數字重新排列成最小的排列(即升序排列)。

必須原地修改,只允許使用額外常數空間。

以下是一些例子,輸入位於左側列,其相應輸出位於右側列。

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

題解

索引i由後往前遍歷數組,直到遇到某個數nums[i-1]<nums[i],

如果不存在,則說明該排列爲最大排列(逆序),則將其順序排序,變爲最小排列;

如果存在,第i-1個數小於第i個數,則在i右邊找到最小的大於第i-1個數的位置,記爲j(要知道此時i右邊的數字是逆序排列的,所以可以順序找到位置j),交換i-1和j上的數字,此時i右邊的數字還是逆序的,將其重排序爲升序,即可得到下一個排列。

這裏需要注意,在重排序時,因爲i右邊的數字們是降序的,所以將其重排序爲升序時,只需要交換第一個和最後一個數字、第二個和倒數第二個數字,…,以此類推,節省排序時間。
代碼如下:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int listLen=nums.size();
        for(int i=listLen-1; i>0; i--){
            if(i==1 && nums[i-1]>nums[i]){
                resortList(nums, 0, listLen-1);
                break;
            }
            else if(nums[i-1] < nums[i]){
                int j=i-1;
                for(int j=listLen-1;j>i-1;j--){
                    if(nums[j]>nums[i-1]){
                        int k=nums[i-1];
                        nums[i-1]=nums[j];
                        nums[j]=k;
                        // swap(nums[j],nums[i-1]);
                        break;
                    }
                }
                // sort(nums.begin()+i,nums.end());
                resortList(nums,i,listLen-1);
                break;
            }
        }
        // return nums;
    }
    void resortList(vector<int>& nums, int start, int end){
        int k;
        while(start<end){
            int k=nums[start];
            nums[start]=nums[end];
            nums[end]=k;
            // swap(nums[start],nums[end]);
            start++;
            end--;
        }
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章