[Leetcode] 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

 

搞清排列過程!

字典序排列
把升序的排列(當然,也可以實現為降序)作為當前排列開始,然后依次計算當前排列的下一個字典序排列。

對當前排列從后向前掃描,找到一對為升序的相鄰元素,記為i和j(i < j)。如果不存在這樣一對為升序的相鄰元素,則所有排列均已找到,算法結束;否則,重新對當前排列從后向前掃描,找到第一個大於i的元素k,交換i和k,然后對從j開始到結束的子序列反轉,則此時得到的新排列就為下一個字典序排列。這種方式實現得到的所有排列是按字典序有序的,這也是C++ STL算法next_permutation的思想。

 1 class Solution {
 2 public:
 3     void nextPermutation(vector<int> &num) {
 4         if (num.size() < 2) return;
 5         int i, k;
 6         for (i = num.size() - 2; i >= 0; --i) if (num[i] < num[i+1]) break;
 7         for (k = num.size() - 1; k > i; --k) if (num[i] < num[k]) break;
 8         if (i >= 0) swap(num[i], num[k]);
 9         reverse(num.begin() + i + 1, num.end());
10     }
11 };

 

如果是找全排列的話,就可以給next_permutation加一個返回值來標記還有沒有下一個permutation了,如果沒有就反回false。

 1 class Solution {
 2 public:
 3     bool nextPermute(vector<int> &num) {
 4         if (num.size() < 2) return false;
 5         int i, k;
 6         for (i = num.size() - 2; i >= 0; --i) if (num[i] < num[i+1]) break;
 7         for (k = num.size() - 1; k > i; --k) if (num[i] < num[k]) break;
 8         if (i >= 0) swap(num[i], num[k]);
 9         reverse(num.begin() + i + 1, num.end());
10         return i >= 0;
11     }
12     
13     vector<vector<int> > permute(vector<int> &num) {
14         vector<vector<int>> res;
15         sort(num.begin(), num.end());
16         do {
17             res.push_back(num);
18         } while (nextPermute(num));
19         return res;
20     }
21 };

 

當然也可以用DFS來做,但是有重復元素的話DFS就有點無能為力了。

 1 class Solution {
 2 public:
 3     void dfs(vector<vector<int>> &res, vector<int> &path, vector<int> &num, int idx) {
 4         if (idx == num.size()) {
 5             res.push_back(path);
 6             return;
 7         }
 8         for (auto v : num) if (find(path.begin(), path.end(), v) == path.end()) {
 9             path.push_back(v);
10             dfs(res, path, num, idx + 1);
11             path.pop_back();
12         }
13     }
14     
15     vector<vector<int> > permute(vector<int> &num) {
16         vector<vector<int>> res;
17         vector<int> path;
18         dfs(res, path, num, 0);
19         return res;
20     }
21 };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM