leetCode 31:下一个序列

目录

一、题目内容

二、解题思路

1.理解题意

2.解题步骤

三、代码实现


一、题目内容

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

输入    输出
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

原题地址:https://leetcode-cn.com/problems/next-permutation/

二、解题思路

1.理解题意

本体的难点在于对于给出的数字序列,下一个序列是怎么产生的 ?题目给出的示例几乎不需要推导,这也增加了理解的难度。不妨给出多一位的序列来演示看看:

1,2,3,4;
1,2,4,3;
1,3,2,4;
1,3,4,2;
1,4,2,3;
1,4,3,2;
2,1,3,4;
2,1,4,3;
2,3,1,4;
2,3,4,1;
2,4,1,3;
2,4,3,1;
.....
4,3,2,1

四位数字的序列,所有按字典序的序列排列共24中,上面列出一部分。根据上面列出的序列,如果将序列看成数字,可以得出比较直观的等价结论:下一个序列等价于大于当前数字的下一个数字。

2.解题步骤

关键是下一个序列的演变逻辑:
 找下一个序列换成找下一个比当前数大的数字会直观很多,比如1,2,4,3的下一个序列是1,3,2,4;

  • 步骤1:因为序列是从小到大排列的,所以从后往前找到第一个不为降序的数字a[i];(比如序列1,2,4,3中的2为从后往前第一个不为降序的数)
  •  步骤2:从后往前找到在a[i]之后的第一个大于a[i]的数字a[j],并交换这两个数;(比如1,2,4,3中的3为第一个大于2的数)
  •  步骤3:把交换之后的位于a[i]之后的数字逆置(使得他们满足升序排列,因为交换之后的数必然满足降序排列,所以只要逆置即可;比如将4,3逆置为3,4便得到了答案需要的写一个序列)

三、代码实现

c++实现:

#include<bits/stdc++.h>  
using namespace std;

void nextPermutation(vector<int>& nums) {
	int n = nums.size() - 2;
	//找到第一个不满足降序的数nums[n]
	while (n >= 0 && nums[n] >= nums[n + 1])
		n--;
	if (n >= 0) {
		int i = nums.size() - 1;
		//找到nums[n]右边第一个大于
		while (i > n && nums[i] <= nums[n])
			i--;
		//交换nums[n]与nums[i]的值
		swap(nums[n], nums[i]);
	}
	//直接交换后面的降序序列,使得得到的序列是最接近条件序列的下一个序列
	reverse(nums.begin() + n + 1, nums.end());
}
int main() {
	//标准库中的同功能的函数
	//	next_permutation(nums.begin(), nums.end());
	vector<int> nums = { 4,5,2,6,3,1 };
	nextPermutation(nums);
	for (int i = 0; i < nums.size(); ++i) {
		cout << nums[i] << " ";
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值