leecode 31.下一个排列(Golang)

题目:

整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

如何解决题目:

主要实现目标可以拆分为几点:

1.比之前要大

2.在比之前要大的基础上 ,要最小的那个

3.如果没有比之前更大的了, 比如 3->2->1 这样的倒序序列,则整体反转

实现步骤:

1.从后向前 查找第一个 相邻升序 的元素对 (i,j),满足 Ai < Aj。此时 [j,end) 必然是降序

2.在 j,end) 从后向前 查找第一个满足 A\[i < Ak 的 k。Ai、Ak 分别就是上文所说的「小数」、「大数」

3.将 Ai 与 Ak 交换 //将最小的数 放到前面

4.可以断定这时 [j,end) 必然是降序,逆置 [j,end),使其升序 //换的那个数 还是小于换之前的,所以依然是降序,要更小一点,所以反转

5.如果在步骤 1 找不到符合的相邻元素对,说明当前 [begin,end) 为一个降序顺序,则直接跳到步骤1

三、具体代码

Go 复制代码
func nextPermutation(nums []int) []int {

	length := len(nums)
	right := length - 1
	left := 0

	flag := false // 用来看是否找到了右边比左边大的值
	for right > left {

		if nums[right] > nums[right-1] { //低位的数字   大于高位的了,也就是找到了

			flag = true
			//从右开始找到第一个大于right-1的 , 也就是找到最小的比    right-1大的值, 交换,交换完  右边还是降序,因为找的是第一个

			for i := length - 1; i >= right; i-- {
				if nums[i] > nums[right-1] {
					nums[i], nums[right-1] = nums[right-1], nums[i]
					break
				}
			}

			reverse(nums, right, length-1)
			break
		}
		right--

	}

	if !flag {
		reverse(nums, 0, length-1)
	}

	return nums

}

func reverse(nums []int, start, end int) {

	for start < end {
		nums[start], nums[end] = nums[end], nums[start]
		start++
		end--
	}

}
相关推荐
智者知已应修善业3 分钟前
【P12159蓝桥杯数组翻转】2025-4-24
c语言·c++·经验分享·笔记·算法·蓝桥杯
小巧的砖头1 小时前
使用SVN+CruiseControl+ANT实现持续集成之一
学习·算法
人道领域1 小时前
【LeetCode刷题日记】贪心算法理论与实战:455.分发饼干最优解
java·开发语言·数据结构·算法·leetcode·贪心算法
小O的算法实验室1 小时前
2026年ACM TCH,动态救护车路径优化:结合 K-means 聚类与多目标粒子群算法两阶段策略
算法
在书中成长2 小时前
HarmonyOS 小游戏《对战五子棋》开发第8篇 - GomokuEngine核心引擎设计(三):五子连珠判定算法
算法·华为·harmonyos
Let's Chat Coding2 小时前
MAC 消息认证码:同时验证来源和完整性
算法·哈希算法
cc.ChenLy4 小时前
算法从入门到精通实战指南
算法
Jerry10 小时前
LeetCode 160. 相交链表
算法
Jerry11 小时前
LeetCode 19. 删除链表的倒数第 N 个结点
算法
金銀銅鐵11 小时前
费马小定理
python·数学·算法