鲁迅说过,这是 2 月的最后一天了,3 月将迎来社招的高峰期,以及春招的高峰期,希望大家都能坚持住,别掉队。二哥的 LeetCode 刷题会继续陪伴大家,希望能给大家带去更多解题的思路,以及学习 Java 的乐趣。
题意
整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。
例如,arr = [1,2,3]
,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1]
。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。
如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
- 例如,arr =
[1,2,3]
的下一个排列是[1,3,2]
。 - 类似地,arr =
[2,3,1]
的下一个排列是[3,1,2]
。 - 而 arr =
[3,2,1]
的下一个排列是[1,2,3]
,因为[3,2,1]
不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。
必须 原地 修改,只允许使用额外常数空间。
难度
中等
示例
例1
输入:nums = [1,2,3]
输出:[1,3,2]
输入:nums = [3,2,1]
输出:[1,2,3]
输入:nums = [1,1,5]
输出:[1,5,1]
分析 1
这道题看起来很唬人,比如题目描述中提到的“字典序”,很多球友第一眼看到这个名词的时候会有点懵,这里简单解释一下。
字典序(dictionary order),又称 字母序(alphabetical order),原意是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。
在这道题目中,字典序其实是指☞ 数字大小的先后顺序。
理解了“字典序”,就能很快理解这道题的题意了:要我们求出比这个数更大的一个排列,比如 123,比它大的是 132,对吧?只需要改变 23 的位置就可以了。312 也比 123 大,只不过它是比 132 更大的一个,不是比 123 更大的一个,官大一级压死人,一级一级来压(😂)。
就好像我们在打扑克牌,我出了一个对 10,那你出对 11 就压住我了,没必要把手里的对 12 先出来,对吧?
再比如 321 已经是「1、2、3」 这三个数字组合中最大的那个了,那就等于说没有更大的了,所以返回 123 这个最小的。
明白了吧?
要想解题,首先得明白题意,所以语文理解是非常重要的,其次是经验(😁)。
那凭借我们以往的经验,可能一下子会想到全排列。就拿 1、2、3、4 来举例吧,全排列如下:
nums = [1,2,3,4]
nums = [1,2,4,3]
nums = [1,3,2,4]
nums = [1,3,4,2]
nums = [1,4,2,3]
nums = [1,4,3,2]
nums = [2,1,3,4]
nums = [2,1,4,3]
nums = [2,3,1,4]
nums = [2,3,4,1]
nums = [2,4,1,3]
nums = [2,4,3,1]
nums = [3,1,2,4]
nums = [3,1,4,2]
nums = [3,2,1,4]
nums = [3,2,4,1]
nums = [3,4,1,2]
nums = [3,4,2,1]
nums = [4,1,2,3]
nums = [4,1,3,2]
nums = [4,2,1,3]
nums = [4,2,3,1]
nums = [4,3,1,2]
nums = [4,3,2,1]
观察nums = [1,3,4,2] -> nums = [1,4,2,3]
这一步,因为4
比3
大,且4
的位置在3
之后,所以将4
与3
交换,必然能够使得nums
变大,交换了之后,则变成了nums = [1,4,3,2]
。
但显然这不是最小的比nums = [1,3,4,2]
大的一个排列,我们还要把3
和2
的位置再翻转一下,才能得到nums = [1,4,2,3]
这个 恰好 比nums = [1,3,4,2]
大一点的排列。
那到底该怎么去找到这个 恰好 比nums
大一点的排列呢?
第一步,我们可以从右向左查找第一个升序的相邻数字对 (i, i+1),满足 nums[i] < nums[i+1]
。
这意味着从 i+1 到末尾的数字都是降序的。如果找不到这样的 i(即整个数组是降序的),这说明当前排列已经是最大的排列,我们只需将其翻转为最小排列即可。
这一步完成之后,并不能保
回复