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;
	}
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章