【Leetcode】 Next Permutation(31)


                                                                        Next Permutation(31)

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

這個題的意思應該能看懂,就是求全排列中,給定排列的下一個排列,剛開始沒有細想,直接從後面開始遍歷,當遇到比自己小的數值時就交換位置,後面的進行排序。試了幾個樣例都對了,於是很開心的提交了。。。leetcode 給出沒有通過的例子,我才反應過來,4202320 的next 是4203022,但是我的程序給出的是4220023。

正確的解法:

1.從後向前遍歷,找到一個打破遞增的位置,例如4202320,0,2,3爲遞增,2變爲遞減。

2.然後將該數字與遞增序列中大於它,並且最小的數字進行交換。位置後面的直接反轉就可以了。(3>2,因此交換位置,變成4203220),將3後的數字反轉,得到4203022。得到正解。

至於爲啥找升序列,我是這樣理解的,升序列是不可能改變數字的位置來變大。只有打破升序才存在可能。剩下的當然是讓大於該位置值的最小值,纔是最接近原來的排列的。並對後面反轉(都是升序,反轉就相當於排序)。

void nextPermutation(vector<int>& nums){
	int length = nums.size();
	int i = length - 1;
	int pos = -1;
	for (; i >= 0; i--){
		if (nums[i] > nums[i - 1]){
			pos = i - 1;
			break;
		}
	}
	if (pos < 0){
		reverse(nums.begin(), nums.end());
		return;
	}
	for (i = length - 1; i > pos; i--){
		if (nums[pos] < nums[i]){
			int temp = nums[pos];
			nums[pos] = nums[i];
			nums[i] = temp;
			reverse(nums.begin() + pos + 1, nums.end());
			return;
		}
	}

}
祝大家身體健康,學習進步!

發佈了44 篇原創文章 · 獲贊 127 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章