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, do not allocate 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

题意:

这道题目是让我们寻找一个数列的下一个排列,也就是按照升序排的最接近的一个排列,把这个数列看成一个整数的话,也就是寻找和这个整数数字相同的下一个数。

刚开始我在做这个的时候,想到的一个算法是,先将整个数列换成一个整数,然后从这个整数开始累加,直到出现和该整数数字相同的数时终止,从高到低取出这个新整数的各个位数,即是答案,但这个答案,很不幸,超时了,也就是当数列比较长时,且数字分布不是很均匀的时候,要累加很多次才能找到答案,因此我们不得不想新的算法来解决这个问题。

一个新的算法如下:

1.若这个数列是当前数中最大的,则直接返回最小的数列即可。

2.从后往前遍历这个数列,当找到第一个a[i] < a[i+1]时跳出循环,记录下此时i的位置,记为k

3.将数列最后一个数和k进行交换。

4.对k+1到最后一个数进行reverse操作,这样得到的结果即为正确的。

下面我来举个例子:例如2431

首先第一个a[i] < a[i+1]的出现在2这个位置,也就是i = 0,然后交换2和1,即 1432, 随后把432进行转置,得到234,最后正确结果即为1234。

一种c++的代码如下:

#include<iostream>
#include<vector>
#include<iterator>

using namespace std;

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
    	int n = nums.size()-1;
    	bool is = false;
        for(int i = 0; i < n; i++) {
			if(nums[i] < nums[i+1]) {
				is = true;
				break;
			}
		}
		if (is == false) {
			reverse(nums.begin(),nums.end());
		} else {
			int k;
			for(int i = n-1; i >= 0; i--) {
				if(nums[i] < nums[i+1]) {
					k = i;
					break;
				}
			}
			int j;
			for(int i = n; i > k; i--) {
				if(nums[i] > nums[k]) {
					j = i;
					break;
				}
			}
			swap(nums[k],nums[j]);
			reverse(nums.begin()+k+1,nums.end());
		}
    }
    void swap(int &a, int &b) {
    	int temp;
    	temp = a;
    	a = b;
    	b = temp;
	}
};


猜你喜欢

转载自blog.csdn.net/zc2985716963/article/details/78374324