題目:算法
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.spa
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).code
The replacement must be in-place, do not allocate extra memory.blog
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
ip
代碼:element
class Solution { public: void nextPermutation(vector<int> &num) { const int len = num.size(); if (len<2) return; std::vector<int>::iterator pivot=num.end(); // find the pivot pointer for (std::vector<int>::iterator i = num.end()-1; i != num.begin(); --i) { if ( *i>*(i-1) ) { pivot = i-1; break; } } // if the largest, directly reverse if ( pivot==num.end() ) { std::reverse(num.begin(), num.end()); return; } // else exchange the value of pivot and it's next larger element std::vector<int>::iterator next_larger_pivot = pivot; for (std::vector<int>::iterator i = num.end()-1; i != num.begin(); --i) { if ( *pivot<*i ) { next_larger_pivot = i; break; } } std::swap(*pivot, *next_larger_pivot); // reverse the pivot's right elements std::reverse(pivot+1, num.end()); } }
Tips:it
上網搜搜Next Permutation的算法,分四步:io
1. 從右往左 找左比右小的左 記爲pivotclass
2. 從右往左 找第一個比pivot大的 記爲next_larger_pivotcoding
3. 交換pivot與next_larger_pivot所指向的元素
4. 讓pivot右邊的元素(不包括pivot)逆序
按照上面的算法,多測測case,找找邊界條件。
注意找到pivot和next_larger_pivot以後要break退出循環。
===================================
第二次過這道題,思路已經記得比較模糊了。能作到的就是撿一遍思路,coding的過程很快。
// from right to left find first violate increase trend int pos1 = -1; for ( int i=nums.size()-1; i>0; --i ) { if ( nums[i]>nums[i-1] ) { pos1 = i-1; break; } } // cout << "pos1:" << pos1 << endl; if ( pos1==-1 ) { std::reverse(nums.begin(), nums.end()); return; } // from right to left find the first larger than pos1 int pos2 = nums.size()-1; for ( int i=nums.size()-1; i>=0; --i ) { if ( nums[i]>nums[pos1] ) { pos2 = i; break; } } // cout << "pos2:" << pos2 << endl; // swap pos1 pos2 std::swap(nums[pos1], nums[pos2]); // reverse from pos1's right to end std::reverse(nums.begin()+pos1+1, nums.end());
這個算法就是個套路,多掃幾遍記住就OK了。