leetcode 31 下一个排列(c++和python)

目录

题目描述:

解题思路: 

C++代码: 

python


 

题目描述:

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

解题思路: 

参考思路:网上看来一个示例,觉得挺好的,也没必要另外找一个了。

6 5 4 8 7 5 1
从排列的后面开始看,想这个排列的下一个排列是怎样的。

(1)1和5调换了没有用。

(2)7、5和1调换了也没有效果,因此而发现了8、7、5、1是递减的。

(3)如果想要找到下一个排列,找到递增的位置是关键。因为在这里才可以使其增长得更大。

(4)于是找到了4,然后在后面找出比4大但在这些大数里面最小的值,并将其两者调换。

那么整个排列就成了:6 5 5 8 7 4 1

(5)然而最后一步将后面的8 7 4 1做一个递增排序。

(6)得到6 5 5 1 4 7 8

(1)由后往前找到递增开始的位置,比如该位置是index-1,数字是4;

(2)找到大于4的数字,且该数字是后面最小的那个。因为后面是逆序的,所以第一个大于4的数字就是要找的,4的索引是index-1;

(3)再将后面的数即index后面从小到大排序。

C++代码: 

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:11.8 MB, 在所有 C++ 提交中击败了48.48%的用户

通过测试用例:265 / 265

class Solution {
public:
	void nextPermutation(vector<int> &num) {
        // 1 由后往前找到递增开始的位置,比如该数字是4
		int index = num.size() - 1;
		while (index > 0 && num[index - 1] >= num[index]){ // 逆序则继续
			index--;
		}

		if (index == 0){ // 整个数组都是逆序的
			sort(num.begin(), num.end());
			return;
		}

		// 2 找到大于4的数字,且该数字是后面最小的那个。
        // 因为后面是逆序的,所以第一个大于4的数字就是要找的,4的索引是index-1
		for (int i = num.size() - 1; i >= index; i--){
			if (num[i] > num[index - 1]){  // 找到,则跳出循环
				swap(num[i], num[index - 1]);
				break;
			}
		}

        // 3 再将后面的数即index后面从小到大排序
		sort(num.begin() + index, num.end()); 
		return;

	}
};

python

执行用时:32 ms, 在所有 Python 提交中击败了7.24%的用户

内存消耗:12.8 MB, 在所有 Python 提交中击败了98.29%的用户

通过测试用例:265 / 265

class Solution(object):
    def nextPermutation(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        # 1 从后往前找,递增开始的位置
        idx = len(nums)-1
        while idx > 0:
            if nums[idx-1] < nums[idx]:  # 如果递增,则跳出循环,此时递增开始的位置是idx-1
                break
            else:
                idx -= 1
        # 2 如果全部逆序,则返回升序排列,list原地排序
        if idx == 0:  # [1]
            nums.sort()
            return nums
        
        # 3 找到后面大于且最接近nums[idx-1]的数字,进行交换
        # 因为是后面是逆序的,所以第一个大于的即是最接近
        for i in range(len(nums)-1, idx-1, -1):
            if nums[i] > nums[idx-1]:  # 找到了,交换,跳出循环
                tmp = nums[i]
                nums[i] = nums[idx-1]
                nums[idx-1] = tmp
                break
        
        # 4 将idx-1后面的数字升序排列
        i = idx
        j = len(nums)-1
        while i < j:
            tmp = nums[i]
            nums[i] = nums[j]
            nums[j] = tmp
            i += 1
            j -= 1
        return nums

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值