LeetCode-031-下一个排列
下一个排列
题目描述:实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
示例说明请见LeetCode官网。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一:遍历数组
首先,如果数组为空或者数组只有一个元素,直接返回;
声明一个变量handled表示是否找到更大的排列,默认是false,left和right分别记录找到更大排列需要调换的数字,然后双重循环遍历数组判断是否存在更大的排列,具体遍历过程如下:
- 从数组的最后一位开始遍历,如果存在前面的数字比当前数字大的,则left和right分别记录当前索引位,并将handled更新为true,然后遍历下一位;
- 遍历过程中需要判断如果找到一种符合条件的数字,要判断是否比之前已得到的情况更优,如果是,更新left和right。
然后根据handled判断,如果为false,说明没有更大的排列,也就是不存在下一个更大排列,将数字重新排列成最小的排列,就是将顺序倒排;如果为true,则需要进行如下处理:
- 首先,将left和right位置的数字调换位置;
- 然后将 right+1 后面的数字倒排,这一步是为了将后面的数字排列成最小的值;
- 然后将 left+1到right-1 之间的数字跟 right+1到nums.length-1 的数字整体调换顺序,这一步也是为了将left后面的数字排列成最小的值;
- 然后将 left+1 位置的数字移到小于它的数字之后,这一步是为了获取最终的排列结果。
import java.util.Arrays;
public class LeetCode_031 {
public static void nextPermutation(int[] nums) {
// 如果数组为空,或者数组的长度为0或者只有一个元素,不用处理
if (nums == null || nums.length < 2) {
return;
}
// 是否找到更大的排列
boolean handled = false;
// 首先找到需要调换位置的数字
int left = -1, right = -1;
for (int i = nums.length - 1; i > 0; i--) {
for (int j = i - 1; j >= 0; j--) {
if (nums[i] > nums[j]) {
if (j > left) {
left = j;
right = i;
} else if (j == left) {
if (i == right) {
left = j;
right = i;
}
}
handled = true;
break;
}
}
}
if (handled) {
// 找到更大的排列
// 1.将 right 的数字和 left 的数字调换位置
exch(nums, left, right);
// 2.首先将 right+1 后面的数字倒排
for (int x = right + 1; x < (nums.length + right + 1) / 2; x++) {
exch(nums, x, nums.length - 1 - (x - right) / 2);
}
// 3.然后将 left+1到right-1 之间的数字跟 right+1到nums.length-1 的数字整体调换顺序
for (int x = right - 1; x >= left + 1; x--) {
for (int y = x; y < nums.length - 1; y++) {
exch(nums, y, y + 1);
}
}
// 4.然后将 left+1 位置的数字移到小于它的数字之后
for (int x = left + 1; x < nums.length - 1; x++) {
if (nums[x] > nums[x + 1]) {
exch(nums, x, x + 1);
} else {
break;
}
}
} else {
// 如果handled为false,说明没有更大的排列,也就是不存在下一个更大排列,将数字重新排列成最小的排列,
// 就是将顺序倒排
for (int i = 0; i < nums.length / 2; i++) {
exch(nums, i, nums.length - 1 - i);
}
}
}
private static void exch(int[] nums, int left, int right) {
int temp = nums[right];
nums[right] = nums[left];
nums[left] = temp;
}
public static void main(String[] args) {
int[] nums = new int[]{4, 2, 0, 2, 3, 2, 0};
System.out.println("=====处理前=====");
Arrays.stream(nums).forEach(num -> {
System.out.print(num + " ");
});
System.out.println();
System.out.println("=====处理后=====");
nextPermutation(nums);
Arrays.stream(nums).forEach(num -> {
System.out.print(num + " ");
});
}
}
【每日寄语】 努力是人生应有的态度,睁开眼就是新的开始。
LeetCode-031-下一个排列的更多相关文章
- LeetCode:下一个排列【31】
LeetCode:下一个排列[31] 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排 ...
- 【LeetCode】下一个排列【找规律】
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常数空间. ...
- Java实现 LeetCode 31下一个排列
31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许 ...
- LeetCode 31. 下一个排列(Next Permutation)
题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常 ...
- leetcode 31下一个排列
/** 验证一般情况(元素数目大于等于3)有几个情况分析:两个特殊情况: 6 5 4 3 2 1 完全反序,这种序列没有下一个排序,因此重新排序1 2 3 4 5 6 1 2 3 4 5 6 完全升序 ...
- LeetCode 31. 下一个排列 | Python
31. 下一个排列 题目 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改, ...
- [LeetCode] Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 031 Next Permutation 下一个排列
实现获取下一个排列函数,这个算法需要将数字重新排列成字典序中数字更大的排列.如果不存在更大的排列,则重新将数字排列成最小的排列(即升序排列).修改必须是原地的,不开辟额外的内存空间.这是一些例子,输入 ...
- [LeetCode] 31. Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 31,Leetcode下一个排列 - C++ 原地算法
题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常 ...
随机推荐
- linux 环境变量配置方式
linux 环境变量可以在多个文件中配置 说明: linux bash 运行模式分为两种: login shell 和non-login shell, 两种登录模式启动是加载的配置文件不一样. 1. ...
- react 局部更新的关键算法 DOM diff算法
下图是diff算法结构的详细解析: 要点总结:DIFF算法在执行时有三个维度,分别是Tree DIFF.Component DIFF和Element DIFF,执行时按顺序依次执行,它们的差异仅仅因为 ...
- JDBC 操作预编译语句中LIKE模糊匹配怎么用
问题描述 在使用JDBC 预编译执行语句时,遇到一个问题,那就是在含有LIKE的查询语句时,我到底怎么使用匹配符%._呢. 如: SELECT * FROM "+LQ_USERS+" ...
- js正则表达式 未提交进行验证
转载请注明来源:https://www.cnblogs.com/hookjc/ function SetInputMust(){ /*var varr=idstr.split(','); idstr ...
- uniapp 小程序全屏的实现
通过设置navigationStyle, 即自定义导航实现背景全屏 参考文章: 微信小程序 自定义头部导航栏 navigationStyle 代码部分 在page.json中, 加入 "n ...
- 基于Autolayout的动画
在修改了约束之后,只要执行下面代码,就能做动画效果 [UIView animateWithDuration:1.0 animations:^{ [添加了约束的view的父控件 layoutIfNeed ...
- MySQL--事件/定时器
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11777311.html MySQL--事件/定时器 : 多个SQL的集合, 定时执行任务. 查 ...
- 《PHP程序员面试笔试宝典》——如何处理与面试官持不同观点这个问题?
如何巧妙地回答面试官的问题? 本文摘自<PHP程序员面试笔试宝典> 在面试的过程中,求职者所持有的观点不可能与面试官一模一样,在对某个问题的看法上,很有可能两个人相去甚远.当与面试官持不同 ...
- R数据分析:数据清洗的思路和核心函数介绍
好多同学把统计和数据清洗搞混,直接把原始数据发给我,做个统计吧,这个时候其实很大的工作量是在数据清洗和处理上,如果数据很杂乱,清洗起来是很费工夫的,反而清洗好的数据做统计分析常常就是一行代码的事情. ...
- CentOS8上安装MySQL
没有选择Win10上安装MySQL,个人感觉比较傻瓜式.同时相对Win10操作系统,个人更熟悉Unix/Linux操作系统,所以选择在CentOS8上安装MySQL数据库. 还是熟悉的yum安装,前提 ...