LeetCode 31. Next Permutation

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.html

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).算法

The replacement must be in-place and use only constant extra memory.數組

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.spa

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

 

 

解答:htm

題目看似不難,其實仍是頗有門道的,須要求「下一個排列」,如何定義下一個,這個問題有些像「數字大小的排序問題」,假設給定一、二、3三個數字,從小到大來作排列,那顯然結果是123,132,213,231,312,321。如今的問題在於,如何釐清算法的流程,假設數組長度爲n,數組名爲nums,步驟以下:blog

  • 從後往前遍歷,找到index爲i的數字,知足nums[i] < nums[i-1],若沒有則序列爲徹底逆序,翻轉整個序列
  • 從後往前,遍歷[i+1,n-1],找到最大的j知足nums[j] > nums[i]
  • 交換nums[j]和nums[i]
  • 將nums[i+1]~nums[n-1]的全部數字翻轉

至於爲什麼要這麼作,個人理解是由於「下一個」,因此要吃透含義,有點相似於數字進位的問題,首先找到一個峯值,接下來尋找比當前的數字大但最接近當前數字的數,因此就有了上面的算法,代碼以下:排序

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int len = nums.size(),i,j;
        for (i = len - 2; i >=0; i--)
            if (nums[i] < nums[i + 1])
                break;
        if (i < 0)
            reverse(nums.begin(), nums.end());
        else
        {
            for (j = len - 1; j > i; j--)
                if (nums[j] > nums[i])
                    break;
            swap(nums[j], nums[i]);
            reverse(nums.begin() + i + 1, nums.end());
        }
    }
};

時間複雜度:O(N)ip

空間複雜度:O(1)leetcode

參考連接:

http://www.javashuo.com/article/p-dohdsmzo-ga.html

https://leetcode.com/problems/next-permutation/discuss/13867/C%2B%2B-from-Wikipedia

相關文章
相關標籤/搜索