LeetCode HOT 100:下一个排列
题目:31. 下一个排列
题目描述:
本题是给你一个整数数组,返回该数组的下一个线性顺序排列。
举个例子:给你一个[1, 2, 3]的数组,他的线性排列顺序从小到大依次为[1, 3, 2],[2, 1, 3],[2, 3, 1],[3, 1, 2],[3, 2, 1]
所以如果给你数组是[1, 2, 3],就应该返回[1, 3, 2],如果数组是[1, 3, 2],就应该返回[2, 1, 3]
题目要求,如果已经是最大线性顺序排列,应当返回最小线性顺序排列,例如数组[3, 2, 1],应返回[1, 2, 3],可以将其理解为一个环。
步骤:
这道题需要从右往左遍历。
1、从右往左遍历,从n - 2下标开始遍历,每一个遍历元素下标为i,如果i一直都大于等于i+1,那么说明该数组已经是最大线性顺序排列,直接反转数组,返回最小线性顺序排列即可。
例如:[5, 4, 3, 3, 1, 1],直接反转数组,返回[1, 1, 3, 3, 4, 5]即可
2、如果在从右往左遍历过程中,一直在升序,突然有一个元素降序了,将该元素下标记录下来,记为较小数,下标为 less
3、然后找到less右边中,大于less的数中最小的那个数的下标,记为more下标。将这两个下标进行交换
4、将原来less下标之后的元素反转一遍,即可得到原数组的下一个线性顺序排列。
解释:
举一个例子,解释上面的操作为什么能得到原数组的下一个线性顺序排列。
原数组[1, 2, 4, 7, 6, 3, 2, 1],less下标元素就是4,因为4是首次降序的元素,所以4后面的元素一定是最大线性顺序[7, 6, 3, 2, 1],
且因为4是首次降序的元素,则后面有比4大的元素,所以4前面的元素肯定不需要动。
所以暂时抛弃4前面的元素,求以4开头一直到结束的数组[4, 7, 6, 3, 2, 1],下一线性顺序即可。
很容易理解,以4开头的[4, 7, 6, 3, 2, 1]数组的下一线性顺序数组一定是以6开头,即下标为more的元素,因为6是4后面大于4的数字中最小的那个,所以6一定是下一线性顺序数组的开头,将4和6交换之后,数组变为[6, 7, 4, 3, 2, 1]。
然后,[4, 7, 6, 3, 2, 1]数组中,是以4开头的最大线性顺序,他的下一线性顺序,肯定是以6开头的最小线性顺序,所以将6后面的元素反转即可,将[6, 7, 4, 3, 2, 1]变为[6, 1, 2, 3, 4, 7]。
最终,原数组[1, 2, 4, 7, 6, 3, 2, 1],下一个线性顺序排列为[1, 2, 6, 1, 2, 3, 4, 7]。
代码:
public void nextPermutation(int[] nums) {
if (nums == null || nums.length < 2) return;
int N = nums.length;
// 从右往左第一次降序的位置
int firstLess = -1;
for (int i = N - 2; i >= 0; i--) {
if (nums[i] < nums[i + 1]) {
firstLess = i;
break;
}
}
if (firstLess == -1) {
reverse(nums, 0, N - 1);
} else {
// 找到最靠右的,同时比nums[firstLess]大的数的下标
int rightClosestMore = -1;
// 这里也可以使用二分进行优化
for (int i = N - 1; i > firstLess; i--) {
if (nums[i] > nums[firstLess]) {
rightClosestMore = i;
break;
}
}
swap(nums, firstLess, rightClosestMore);
reverse(nums, firstLess + 1, N - 1);
}
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
swap(nums, start, end);
start++;
end--;
}
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
LeetCode HOT 100:下一个排列的更多相关文章
- [LeetCode] Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- Leetcode题目31.下一个排列(中等)
题目描述: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外 ...
- 【LeetCode 31】下一个排列
题目链接 [题解] 从右往左找第一个下降的位置i(即满足nums[i]<nums[i+1]); 然后在[i+1..len-1]这个区间里面找到一个最大的下标k,使得nums[k]>nums ...
- LeetCode:下一个排列【31】
LeetCode:下一个排列[31] 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排 ...
- [LeetCode] 31. Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 31,Leetcode下一个排列 - C++ 原地算法
题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常 ...
- 【LeetCode】下一个排列【找规律】
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常数空间. ...
- Java实现 LeetCode 31下一个排列
31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许 ...
- LeetCode(31): 下一个排列
Medium! 题目描述: (请仔细读题) 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列) ...
- 【LeetCode每天一题】Next Permutation(下一个排列)
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
随机推荐
- Elasticsearch中字段的类型
在Elasticsearch中,每一个字段都有一个类型(type).以下为Elasticsearch中可以使用的类型:
- linux搭建内网邮件服务器
一.配置发件服务器 1.1 根据现场IP,配置主机名 vi /etc/hosts 192.168.40.133 mail.test.com 将主机名更改为邮件服务器域名mail.test.com 1. ...
- 驱动开发:通过Async反向与内核通信
在前几篇文章中给大家具体解释了驱动与应用层之间正向通信的一些经典案例,本章将继续学习驱动通信,不过这次我们学习的是通过运用Async异步模式实现的反向通信,反向通信机制在开发中时常被用到,例如一个杀毒 ...
- Spring让人眼前一亮的11个小技巧
前言 我们一说到spring,可能第一个想到的是 IOC(控制反转) 和 AOP(面向切面编程). 没错,它们是spring的基石,得益于它们的优秀设计,使得spring能够从众多优秀框架中脱颖而出. ...
- Ruoyi字典源码学习
此文章属于ruoyi项目实战系列 使用目的 什么是字典数据:具体的值(0,1,"Y","N"),对应具体的业务逻辑("男","女& ...
- Windows开启关闭测试模式的方法(含开启测试模式失败的解决办法)
前言: 内含:Windows开启关闭测试模式的方法.开启测试模式失败的解决办法.win10进入bios的方式.BitLocker恢复方式. 对于互联网从业者来说 ...
- 关于Springboot启动报错 Whitelabel Error Page: This application has no explicit mapping
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as ...
- python的list,dict,set
list # 1.list() 把可迭代对象转换成list,即for循环遍历的可迭代对象 my_str = "abcdef" new_list = list(my_str) pri ...
- 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路
本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...
- pinpoint:查看hbase表和修改数据过期时间
先做个记录,监控数据量过大时可以设置表的数据过期时间来清理数据. 1. 查找本地数据表大小 [root@ZWZF-CWY-LZY-12 ~]# cd /home/pinpoint/hbase/data ...