Crack LeetCode 之 31. Next Permutation

Leetcode link: https://leetcode.com/problems/next-permutation/

这道题要求不能使用extra memory,所以不能使用递归。下面的算法使用3次扫描解决这个问题,一共4步:
(一) 从右往左扫,找到第一个比前一个元素小的元素,其索引为p;
7 8 9 3 2 1
这里p=1
(二) 从右往左扫,找到第一个比p指向的元素大的元素,其索引为q;
7 8 9 3 2 1 
这里q=2
(三) 交换 p 和 q指向的元素;
交换之前:
7 8 9 3 2 1 
交换之后:
7 9 8 3 2 1 
(四) 把从p+1到数组结束的所有元素倒序。
7 9 1 2 3 8 

以下是C++代码,时间复杂度是O(n),空间复杂度是O(1)。

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        if (nums.size()<2)
            return;

        int p = 0;
        for (int i = nums.size() - 2; i >= 0; i--) {
            if (nums[i]<nums[i + 1]) {
                p = i;
                break;
            }
        }

        int q = 0;
        for (int i = nums.size() - 1; i>p; i--) {
            if (nums[i]> nums[p]) {
                q = i;
                break;
            }
        }

        if (p == 0 && q == 0) {
            reverse(nums, 0, nums.size() - 1);
            return;
        }

        int temp = nums[p];
        nums[p] = nums[q];
        nums[q] = temp;

        reverse(nums, p + 1, nums.size() - 1);
    }

    void reverse(vector<int>& nums, int left, int right) {
        while (left<right) {
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
            left++;
            right--;
        }
    }
};

猜你喜欢

转载自blog.csdn.net/tassardge/article/details/82346796