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;
}