LeetCode 31.NextPermutation

本文介绍了解决LeetCode 31题“下一个排列”的两种方法。第一种方法简单直接,使用C++标准库函数next_permutation。第二种方法深入解析了寻找下一个字典序排列的具体步骤,包括定位关键元素、交换并反转等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode 31.NextPermutation

Description:

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, do not allocate extra memory.

Example:

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


分析:

这道题比较难,解法也比较难想到,我在discuss和solution上看到的解法都是同样的原理,具体如下:
第一种做法:利用库函数next_permutation即可返回下一个排列。
第二种做法:

  • 首先从数组最右边开始往前比较,这时候是一个递增序列,然后找到第一个打破这个递增序列的数,其位置记为k。
  • 如若没找到,说明整个数组从左到右为递减序列,是最后一个排列,直接返回倒过来的数组即可。例如3->2->1 整个为递减序列,直接利用reverse函数返回1->2->3
  • 然后,从数组最右边开始往前遍历,与nums[k]比较,找到第一个大于nums[k]的数,并将其位置记为m。
  • 接下来,将nums[k]和nums[m]换位置,利用swap函数。
  • 最后从nums[k+1]开始直至数组尾部,全部颠倒过来,即是下一个排列。

代码如下:

第一种解法:利用next_permutation函数:

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        next_permutation(nums.begin(), nums.end());
    }
};

第二种解法:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int k = -1;
        for (int i = nums.size() - 2; i >= 0; i--) {
            if (nums[i] < nums[i + 1]) {
                k = i;
                break;
            }
        }
        if (k == -1) {
            reverse(nums.begin(), nums.end());
            return;
        }
        int m = -1;
        for (int i = nums.size() - 1; i > k; i--) {
            if (nums[i] > nums[k]) {
                m = i;
                break;
            }
        }
        swap(nums[k], nums[m]);
        reverse(nums.begin() + k + 1, nums.end());
    }
};
int main() {
    int n;
    cin >> n;
    vector<int> nums;
    for (int i = 0; i < n; i++) {
        int t;
        cin >> t;
        nums.push_back(t);
    }
    Solution s;
    s.nextPermutation(nums);
    for (int i = 0; i < n; i++) {
        cout << nums[i] << " ";
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值