Crack LeetCode 之 31. Next Permutation

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

解这道题需要先了解什么是“下一个 排列”的算法,否则单凭题目中给出的几个例子根本无从下手。参考这个链接:https://www.cnblogs.com/ECJTUACM-873284962/p/6390591.html

这道题要求不能使用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++代码和python代码,时间复杂度是O(n),空间复杂度是O(1)。

这道题还是需要一定的数学知识,面试者要能够观察出来排列的递增规律,也能看出来面试者是否聪明。本题可以用来考察面试者是否考虑问题全面,例如p和q等于0的情况。

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--;
        }
    }
};
class Solution:
	def nextPermutation(self, nums):
		if nums is None or len(nums) < 2:
			return

		p = 0
		for index in range((len(nums) - 2), -1, -1):
			if (nums[index+1] > nums[index]):
				p = index
				break

		q = 0
		for index in range((len(nums) - 1), -1, -1):
			if (nums[index] > nums[p]):
				q = index
				break

		if p == 0 and q == 0:
			return self.reverseOrder( nums, 0, len(nums)-1 )
			
		nums[p] = nums[p]^nums[q]
		nums[q] = nums[p]^nums[q]
		nums[p] = nums[p]^nums[q]

		return self.reverseOrder( nums, p+1, len(nums)-1 )

	def reverseOrder(self, nums, left, right ):
		while left < right:
			nums[left] = nums[left]^nums[right]
			nums[right] = nums[left]^nums[right]
			nums[left] = nums[left]^nums[right]

			left = left + 1
			right = right - 1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值