Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
題目鏈接:https://leetcode-cn.com/problems/permutations/
思路
法一:回溯法
之前遇到的問題都是取連續的鏈,本題要取的元素並不連續。
這邊用了一個數組在標記元素是否用過了,能夠保證元素有重複值的情況也能使用。
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
if(nums.size()<=0) return res;
bool visit[nums.size()] = {false};
return trace(nums, visit);
}
vector<vector<int>> trace(vector<int> nums, bool visit[]){
vector<vector<int>> res;
for (int i = 0; i<nums.size(); ++i){
if(!visit[i]){
visit[i] = true;
auto vec = trace(nums, visit);
visit[i] = false;
if(vec.size()<=0){
vector<int> tmp = {nums[i]};
res.push_back(tmp);
}else{
for(int j = 0; j<vec.size(); ++j){
vec[j].push_back(nums[i]);
res.push_back(vec[j]);
}
}
}
}
return res;
}
};
代碼優化
上面的代碼是向下遞歸的時候進行了一次循環,返回結果後又對結果做了循環。
如果把兩次循環合併,不是把下面結果向上傳,而是上面的結果向下傳到底後直接儲存,可以降低運行時間。
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> permute(vector<int>& nums) {
if(nums.size()<=0) return res;
bool visit[nums.size()] = {false};
vector<int> cur;
trace(nums, 0, cur, visit);
return res;
}
void trace(vector<int> nums, int index, vector<int> &cur, bool visit[]){
if(index==nums.size()){
res.push_back(cur);
return;
}
for (int i = 0; i<nums.size(); ++i){
if(!visit[i]){
cur.push_back(nums[i]);
visit[i] = true;
trace(nums, index+1, cur, visit);
visit[i] = false;
cur.pop_back();
}
}
}
};
法二:庫函數next_permutation
這個方法是看分享才知道的。說實話有點作弊,做筆試或比賽的時候可以用,面試的話肯定還會細問next_permutation的實現。
next_permutation(開始位置,結束位置-不包含):變換範圍 [first, last)
爲來自所有按相對於 operator<
或 comp
的字典序的下個排列。若這種排列存在則返回 true ,否則變換範圍爲首個排列(如同用 std::sort(first, last)
)並返回 false 。
這種方法應該屬於特殊例子,沒有仔細調研來龍去脈,暫時先參考這篇博文的解釋學習了下,如果思路比較通用的話以後應該還會遇到,暫時先挖個坑背誦一下哈哈。
c++<algorithm>庫中的解釋:https://zh.cppreference.com/w/cpp/algorithm/next_permutation
代碼來源:https://leetcode-cn.com/problems/permutations/solution/hui-su-next_permutation-by-ogeazjciet/
vector<vector<int>> permute(vector<int>& nums) {
sort(nums.begin(), nums.end());
do {
result.push_back(nums);
}while (next_permutation(nums.begin(), nums.end()));
return result;
}