1. 程式人生 > >【LeetCode】31. Next Permutation(C++)

【LeetCode】31. Next Permutation(C++)

地址:https://leetcode.com/problems/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,31,3,2
3,2,11,2,3
1,1,51,5,1

理解:

按字典序排列的下一個比這個元素大的元素。如果已經是最大,就返回最小。
想到了找到陣列中後一個大於前一個的位置,但是具體怎麼換還是比較懵逼。看了看別人給的解法,總結了一下思路。

  • 從後向前找到第一個位置i
    ,使得nums[i-1]<nums[i]
    • 如果存在,需要調整的就是從i-1到陣列末尾的元素。注意到i的位置滿足,從i到size()-1是不增的。且從nums[i]-nums[nums.size()-1]一定能找到一個比nums[i-1]大的元素。
      • 尋找i-size()-1的最小的大於nums[i-1]的元素,記為nums[j]
      • 交換nums[i-1]nums[j]。注意到交換後,從nums[i]nums[nums.size()-1]仍然是非增的。因此,把後面的直接翻轉,就得到了字典序第一個比輸入大的結果。
    • 如果不存在,直接翻轉整個陣列。

實現:

class Solution {
public:
	void nextPermutation(vector<int>& nums) {
		int i;
		for (i = nums.size() - 1; i > 0; --i) {
			if (nums[i - 1] < nums[i])
				break;
		}
		if (i > 0) {
			int j = nums.size() - 1;
			while (nums[j] <= nums[i - 1])
				--j;
			swap(nums[i - 1], nums[j]);
		}
		reverse(nums.begin() + i, nums.end());
	}
};

後記:

這個竟然有一個對應的庫函式,也是十分神奇。。