ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LeetCode 31 下一个排列

2022-02-09 14:02:35  阅读:120  来源: 互联网

标签:排列 nums -- 31 区间 升序 LeetCode


题目链接:LeetCode 31 下一个排列

题目大意:

题解:
注意到下一个排列总是比当前排列要大,除非该排列已经是最大的排列。我们希望找到一种方法,能够找到一个大于当前序列的新序列,且变大的幅度尽可能小。具体地:

  1. 我们需要将一个左边的“较小数”与一个右边的“较大数”交换,以能够让当前排列变大,从而得到下一个排列。
  2. 同时我们要让这个“较小数”尽量靠右,而“较大数”尽可能小。当交换完成后,“较大数”右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。

具体地,我们这样描述该算法,对于长度为\(n\)的排列\(a\):

  1. 首先从后向前查找第一个顺序对\((i,i+1)\),满足\(a[i]<a[i+1]\)。这样“较小数”即为\(a[i]\)。此时\([i+1,n)\)必然是下降序列。
  2. 如果找到了顺序对,那么在区间\([i+1,n)\)中从后向前查找第一个元素\(j\)满足\(a[i]<a[j]\)。这样“较大数”即为\(a[j]\)。
  3. 交换\(a[i]\)与\(a[j]\),此时可以证明区间\([i+1,n)\)必为降序。我们可以直接使用双指针反转区间\([i+1,n)\)使其变为升序,而无需对该区间进行排序。
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int i = nums.size() - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        if (i >= 0) {
            int j = nums.size() - 1;
            while (nums[i] >= nums[j]) {
                j--;
            }
            swap(nums[i], nums[j]);
        }
        reverse(nums.begin() + i + 1, nums.end());
    }
};

标签:排列,nums,--,31,区间,升序,LeetCode
来源: https://www.cnblogs.com/IzumiSagiri/p/15874671.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有