LeetCode:31. Next Permutation

题目:

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

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.

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

大意是将数字重新排列组合,使之成为比现有数大的数中最小的那个。

这题有点饶人,需要自己多举几个例子演算一下。
下面是我总结出的步骤:
1)找到符合(1)m < n (2) nums[m] < nums[n]这样的m,n组合,找到这样的组合中m最大的一个(m和n都是索引)。如果没有这样的组合,说明数字都是降序排列,按照题目要求,将整个数组倒过来即可
2)然后符合上述两个情况的n中,找到nums[n]最小的一个,将nums[m]和nums[n]进行swap
3)对m之后的元素进行升序排序

下面是代码:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {//找倒序
        if (nums.size() < 2)
            return;
        using std::swap;
        int m, n;
        bool found_m = false;
        m = 0;
        for (int i = nums.size()-1; i >= m; --i) { //注意这里的i >= m
            for (int j = i-1; j >= m; --j) //这里的j >= m,因为至少要>=现有的m,才有比较的意义
                if (nums[j] < nums[i]) {
                    found_m = true;
                    m = j;
                }
        }
        if (!found_m) {
            reverse(nums);
            return;
        }
        int nVal_min = INT_MAX;
        for (int i = m+1; i < nums.size(); ++i) 
            if (nums[m] < nums[i] && nums[i] < nVal_min){
                nVal_min = nums[i];
                n = i;
            }
 
        swap(nums[m], nums[n]);
        sort(nums.begin()+m+1, nums.end());
        
        return;
    }
    
private:
    void reverse(vector<int>& nums) {
        using std::swap;
        auto sz = nums.size();
        for (int i = 0; i < sz/2; ++i)
            swap(nums[i], nums[sz-1-i]);
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43462819/article/details/84378106