Array - 31. Next Permutation
时间:2022-07-25
本文章向大家介绍Array - 31. Next Permutation,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
- Next Permutation
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place and use only constant extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
思路:
题目意思是找出一个比给定数组大的组合中最小的一个组合,比如比123大的组合当中最小的就是132,题目要求在原数组中操作,常数的空间复杂度,所以只能通过交换原数组的方式来实现。
- 首先,可以明确的是一个数组,从小到大排序的组合一定是最小的,按从大到小排列的组合一定是组合中最大的。
- 题目中规定了最极端的情况就是两个数组有序,那就直接翻转一下数组就可以得到结果,比如
1 2 3 4 5
翻转为5 4 3 2 1
。 - 如果一个数组无序,下一个最大的就取决于最后一段,是有极大值的拐点,还是极小值的拐点, 可以理解为升序代表最小,降序代表最大,先看极小值拐点的情况,这种情况直接把降序的两个点交换一下。至于有极大值点的那种情况,就在上升趋势中找出第一个比顶点小,和下降趋势比这个点大的做一下交换,就保证了上升趋势最小的性质,然后把后半部分的下降趋势翻转,就变成了代表最小的升序。而极小值的情况,可以看做是极大值的特殊情况,只不过下降趋势长度为零。
代码:
go:
func nextPermutation(nums []int) {
if nums == nil || len(nums) == 0 {
return
}
size := len(nums)
start := size - 2
// 从后往前找,找到第一个比后一个小的位置
for start >= 0 && nums[start] >= nums[start + 1] {
start--
}
// 如果这个数不是递减,说明,需要和后面的第一个比他大的做一个调换
if start >= 0 {
// 找到第一个比当前数小的进行交换
k := size -1
for ; k > start && nums[k] <= nums[start]; {
k--
}
nums[k], nums[start] = nums[start], nums[k]
}
// 这时候从start+1到数组结束是一个严格递减的数组,只用翻转一下,就会变成一个严格递增,也就是最小的数
for i, j := start + 1, size - 1; i < j; {
nums[i], nums[j] = nums[j], nums[i]
i++
j--
}
}
- 1601: [Usaco2008 Oct]灌水
- 1657: [Usaco2006 Mar]Mooo 奶牛的歌声
- 1610: [Usaco2008 Feb]Line连线游戏
- 1012: [JSOI2008]最大数maxnumber
- 1430: 小猴打架
- 1202: [HNOI2005]狡猾的商人
- 1059: [ZJOI2007]矩阵游戏
- 3039: 玉蟾宫
- 大公司都有哪些开源项目之腾讯
- Vue拖拽组件开发实例
- 一小时培训之神经网络入门
- 【LeetCode 290】 关关的刷题日记28 Word Pattern
- Redis知识点速查
- 上传伪技术~很多人都以为判断了后缀,判断了ContentType,判断了头文件就真的安全了。是吗?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- R语言预测人口死亡率:用李·卡特(Lee-Carter)模型、非线性模型进行平滑估计
- 前端的发展历程
- R语言蒙特卡洛计算和快速傅立叶变换计算矩生成函数
- Visual Studio 中万能头文件编译不了的解决方案
- Difference in two ways of using lower_bound [C++]std::set::lower_bound与std::lower_bound
- 迷你版Vue--学习如何造一个Vue轮子
- 如何用R语言绘制生成正态分布图表
- hdu 5143 NPY and arithmetic progression(暴力+思维)
- 正则表达式之简易markdown文件解析器
- 2015.CCF计算机软件能力认证试题第二题
- Codeforces Round #547 (Div. 3)A. Game 23
- Codeforces Round #547 (Div. 3)C. Polycarp Restores Permutation
- 动态规划入门_数塔问题
- Rust所有者被修改了会发生什么?
- 如何编写高质量代码