LeetCode--31.下一个排列

解题思路:

1.获取信息:

(1)整数数组的排列是将其中的整数按一定顺序排列

(它给出了例子来帮你理解这句话,如下)

例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3][1,3,2][3,1,2][2,3,1]

(2)数组的下一排序,就是下一个字典序更大的排序

(它也给出了例子来帮助你理解这句话,如下)

例如,arr = [1,2,3] 的下一个排列是 [1,3,2]

类似地,arr = [2,3,1] 的下一个排列是 [3,1,2]

arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。

(3)它会给出一种排列,要求我们将它原地修改为下一排列

2.分析题目:

(1)整数数组的排列,你应该看例子就可以懂得,我就不进行讲解了

(2)字典序,大家还记得字典序吗?

我们在进行字符串的比较的时候,会用到字典序,有没有激起你的回忆呢?没有,也没关系,我会说

字典序,用来衡量对象的大小,我们一般是先比较两个字符串中第一位字符的大小,谁大,谁的字典序就大,如果一样,那就比较下一位,以此类推

那么我们可以知道,靠前的位数,大小的权重比较大

另外字典序的比较,我们应该就知道是什么了吧,不知道也没关系,看看例子就懂了

(3)要求我们将原排列原地修改成下一排列

原地修改:说明禁止了我们使用辅助存储空间,但是说了可以使用额外常数空间(这个额外常数空间其实说了跟没说一样)

下一排列:意味着我们这个下一排列要比原排列大,但两者的字典序是最接近的

(4)重点来咯(先说好,其实我们可以将任意几个数看成一个整体,它们也拥有自己的字典序)(你如果没看懂,也没关系,我在下面的代码也会讲解一遍)

有了这么多个例子,又加深了对题目的了解,咱们应该可以知道它是什么意思了吧

我们知道,要尽量只改变数组后面的几个数的位置才能尽可能接近原排列的字典序的同时且大于它,因为越靠前大小的权重就越大了

那么我们怎么确定要改变后面几个数的位置呢?

前面有两个例子,如下

1, 2, 3\],它的下一排列,是\[1, 3, 2

你应该知道,为什么前面那个1不动吧,因为后面可以在保留1为首位的同时,组合成一个字典序更大的下一排列对吧,所以只改变后面两个位置

那怎么确定,后面能不能组合成一个较大的字典序呢?

就是通过它们排列的位置,能改变成一个较大的字典序的情况就是,前面的那个数是小于后面那个数的,所以换过来就可以变成一个较大的字典序了

当我们找到前面的数(p2)比后面的数(p1)小的那个位置的时候,我们就将前面的数(p2)依次与后面的所有的数(>=p1)相比较,找到一个最接近的数,与前面的数(p2)交换位置,再对

前面的数(p2)的后面所有的数按从小到大的顺序排列(因为要保证尽量接近,那就保持最小的字典序)

3,2,1\],它的下一排列,是\[1, 2, 3

你发现没有,一般从小到大排列的部分是最小值,从大到小排列的部分是最小值

你想从小变大,就将从小到大的顺便变成从大到小

你再看看上面的例子和我讲解的那些,是不是会感觉要好一点

3.示例查验:

示例1,示例2和示例3:你可以检验一下自己的思路是否正确

4.尝试编写代码

(1)常规法(平平无奇)

思路:可以想成一个截断的方法,越靠前的数不是大小的权重越大吗?那我们就将前面我们根本用不到的数给切掉,只考虑后面的数,那就新形成了一个数组嘛,我们就求这个数组的下一排列,是不是就简化了一下,反正求下一排列,前面那些权重比较大的数也动不得

要改变的位置就像我上面说的,就那样找出来

你可能有疑惑,是啊,我找出来了,但是,为什么要将前面的数(p2)与它后面的所有的数相比较,找出最接近它的数并且要比前面的数大呢?

因为你是要重排剩下的这些数,它们每一个你都不能漏下,那要排成下一排列,那就只能找一个这样的数,排到最前面,才可以保证,它会变大,但不会变得太大

至于,为什么交换后,要按从小到大的顺序排列后面的所有的数,也是为了尽量不让它变太大,因为是下一排列嘛

cpp 复制代码
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int size=nums.size();//数组的大小
        int p1=size-1;//一个放在倒数第一位的指针
        int p2=p1-1;//一个放在倒数第二位的指针
        while(p2>=0){//从后往前扫描
            if(nums[p2]<nums[p1]){//查找前面的数小于后面的数的情况
                int cap=INT_MAX;//间隔,我们将它初始化为最大值
                int web=p1;//p2与之交换的位置
                for(p1;p1<size;p1++){//找到最接近且大于p2的数
                    if(nums[p1]>nums[p2]&&nums[p1]-nums[p2]<cap){
                        cap=nums[p1]-nums[p2];
                        web=p1;
                    }
                }
                swap(nums[p2],nums[web]);//交换它们的位置
                sort(nums.begin()+p2+1,nums.end());//按从小到大的顺序排列后面的数
                return;
            }
            if(p2==0){//如果数组是最大的字典序
                sort(nums.begin(),nums.end());//换成最小的字典序
                return;
            }
            p1--;p2--;
        }
    }
};

我已经竭尽全力写得更通俗易懂了,希望你能理解这道题,虽然字有点多,但也是有一点作用的

如果我写得太专业化或者太简练,其实我自己是爽了,看着帖子也比较好看,你点进来也比较舒心,但是我害怕不能让你理解,太华而不实也不行

唉,希望能帮上你吧,但也不能忘了,纸上得来终觉浅,绝知此事要躬行

相关推荐
艾莉丝努力练剑19 分钟前
【优选算法必刷100题】第031~32题(前缀和算法):连续数组、矩阵区域和
大数据·人工智能·线性代数·算法·矩阵·二维前缀和
醉颜凉20 分钟前
环形房屋如何 “安全劫舍”?动态规划解题逻辑与技巧
c语言·算法·动态规划
大雨淅淅24 分钟前
一文搞懂动态规划:从入门到精通
算法·动态规划
不去幼儿园26 分钟前
【启发式算法】灰狼优化算法(Grey Wolf Optimizer, GWO)详细介绍(Python)
人工智能·python·算法·机器学习·启发式算法
随意起个昵称27 分钟前
【二分】洛谷P2920,P2985做题小记
c++·算法
没书读了33 分钟前
计算机组成原理-考前记忆清单
线性代数·算法
Hcoco_me1 小时前
大模型面试题5:矩阵(M*M)特征值分解的步骤
算法·机器学习·矩阵
非著名架构师2 小时前
极端天气下的供应链韧性:制造企业如何构建气象风险防御体系
大数据·人工智能·算法·制造·疾风气象大模型·风光功率预测
星轨初途2 小时前
数据结构排序算法详解(2)——选择排序(附动图)
c语言·数据结构·经验分享·笔记·b树·算法·排序算法
kaikaile19953 小时前
基于 MATLAB 的室内三维定位
算法