算法 leetcode 31 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

本题的意思是输入一个序列,求此序列全排列的下一个序列是什么?题目要求只能在原vector中进行变换,允许使用固定的额外存储(可以理解为不以vector的长度的改变而改变)。同时还给出了一个实例。

思路分析

首先需要了解全排列的序列变化方法才能很好的完成这个题目。
一般的,序列的下一个全排列序列遵循以下算法:
1、序列从左至右依次开始比较,某数遇到的下一个数比某数要大则标记该数。
比如: 2, 1, 4, 6, 3, 5
此时标记1,此时位于序列的第二个位置上。
2、此时再查找已标记的数后面比已标记的数大的集合中最小的数。
比如:2, 1, 4, 6, 3, 5
此时标记3,位于此序列的第四个位置上。
3、利用前面标记的两个位置,对两个位置及中间的数进行倒置。
比如:2, 1, 4, 6, 3, 5
倒置后:2, 36, 4, 1, 5
对于特殊情况:
6, 5, 4, 3, 2, 1
直接转置为:
5, 4, 3, 2, 1, 6

详细代码

class Solution {
public:
	void nextPermutation(vector<int>& nums) {
		int length = nums.size();
		if (length <= 1)
			return;
		int temp = 0;
		int j = 0;
		bool flag = true;
		int t = 0;
		for (int i = length - 1; i >= 1; --i) {
			if (nums[i] <= nums[i - 1]) {
				t = i;
				continue;
			}else {
				temp = nums[i];
				j = i;
				flag = false;
				break;
			}
		}
		if (!flag) {
			if (j == length - 1) {
				nums[j] = nums[j - 1];
				nums[j - 1] = temp;
			}else {
				int k = length - 1;
				int m = j;
				temp = -1;
				while (k >= j) {
					if (nums[k] > nums[j - 1] ) {
						if (temp == -1) {
							temp = nums[k];
							m = k;
						}
						else {
							if (nums[k] < temp) {
								temp = nums[k];
								m = k;
							}
						}
						
					}
					k--;
				}
				nums[m] = nums[j - 1];
				nums[j - 1] = temp;
				Swap(nums, j, length - 1);
			}
			return;
		}

		temp = nums[length - 1];
		for (int i = length - 1; i > length - 1 - i; --i) {
			temp = nums[i];
			nums[i] = nums[length - 1 - i];
			nums[length - 1 - i] = temp;
		}

		return;
	}
private:
	void Swap(vector<int> & nums, int j, int length) {
		for (int i = length; i > j; --i, ++j) {
			int temp = nums[i];
			nums[i] = nums[j];
			nums[j] = temp;
		}
		return;
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值