中等
相关标签
相关企业
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1] 输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1] 输出:[[1]]
提示:
1 <= nums.length <= 6-10 <= nums[i] <= 10nums中的所有整数 互不相同
解法:
这道题是一道回溯剪枝的模版题,形如求全排列,求二叉树到某个节点的所有的路径都可以用这套模版
void backtrack(State* &state,vector<Choice*> &choices,vector<State*> &res)
{
if(isSolution(state,choices)){
recordSolution(state,res);
return;
for(Choice* choice:choices)
{
if(isValid(choices))//剪枝
{
makeChoice(state,choice);
backtreck(state,choices,res);//向下探路
undoChoice(state);//回溯
}
}
}
}
这道题中我们判断isSolution的条件就是state的长度等于choices,isValid的条件就是没有重复数字,这里我们利用一个哈希表selected来存储数字是否被插入过了,
makeChoice就是添加新的choice到state当中,然后设置selected[choice]=true,undoChoice就是将state最后一个元素pop,并且设置哈希表当中的相应元素为false
答案代码如下
class Solution {
public:
bool isSolution(vector<int> &state,vector<int> &choices)
{
return state.size()==choices.size();
}
void addSolution(vector<int> &state,vector<vector<int>> &res)
{
res.push_back(state);
}
bool isValid(unordered_map<int,bool>selected,int choice)//当没有重复元素的时候
{
return !selected[choice];
}
void makeChoice(vector<int> &state,int choice,unordered_map<int,bool>&selected)
{
state.push_back(choice);
selected[choice]=true;
}
void undoChoice(vector<int> &state,unordered_map<int,bool> &selected){
int i=state.back();
state.pop_back();
selected[i]=false;
}
void backTrack(vector<int>&state,vector<int> &choices,unordered_map<int,bool>&selected,vector<vector<int>>&res)
{
if(isSolution(state,choices))
{
addSolution(state,res);
return;
}
for(int i=0;i<choices.size();i++)
{
if(isValid(selected,choices[i]))
{
makeChoice(state,choices[i],selected);
backTrack(state,choices,selected,res);
undoChoice(state,selected);
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
unordered_map<int,bool>selected;
for(int var:nums)
{
selected[var]=false;
}
vector<vector<int>> res={};
vector<int> state={};
backTrack(state,nums,selected,res);
return res;
}
};

1万+

被折叠的 条评论
为什么被折叠?



