1. 程式人生 > 實用技巧 >leetcode31 - Next Permutation - medium

leetcode31 - Next Permutation - medium

Implementnext 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 placeand use only constantextra 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

這道題的關鍵是要找到從哪個點去backtrack(只是突破口,和backtrack也沒關係)。思考permutations裡我們是如何對每個slot進行填數的:假設nums是遞增的,填當前slot的時候從頭開始挨個遍歷nums,也就是說[1,2,3]我們填到1,3

x的這個3的時候,它已經是這個slot能填的最大的數了,不應該去替換它。Generalize一下,從後往前找,任何strictly decreasing section都沒啥能動的了,找到第一對nums[pos]<nums[pos+1]的對子,這個pos就是我們要修改的slot。再從pos之後找個比它大的數和它換,最後保證pos之後是sorted的以滿足答案是最小的。

一開始標記一下pos=-1,掃一遍pos還是-1說明不存在,直接重排整個陣列。排序的時候reverse複雜度好於sort。

實現:

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