上周刷了括号匹配的问题,这周开始刷排列。
谈到排列,那算法就没得选。DFS。
比如给了一组数{1, 2, 3},让找出所有的排列。
那大家的思路一定是
1. 先把各个元素作为新的排列的第一个元素:
{1}
{2}
{3}
2. 然后每个排列中再依次把没有访问的数字插进去
{1,2}
{1, 3}
{2, 1}
{2, 3}
{3, 1}
{3, 2}
3. 重复第二步直到每个排列的长度等于3.
所以DFS来做就是基本的解法。框架如下:
DFS(result, curPerm, inputVector){
当已经排序完的组合长度和输入的数组长度一样时候
更新结果并退出递归
}
for(auto i: inputVector){
if(i 访问过)
continue;
把新的元素i放到curPerm里
递归DFS()
恢复当前for loop 刚刚开始的状态,进行下一步for loop
}}
46. Permutations 就是按照这个框架写的代码
class Solution {
public:
void help(vector<vector<int>> &ret,vector<int> &curVec,vector<int>& nums, unordered_set<int> visited)
{
if(curVec.size() == nums.size()){
ret.push_back(curVec);
return;
}
for(int i=0;i<nums.size();i++) {
if(visited.count(nums[i]) == 1)
continue;
curVec.push_back(nums[i]);
visited.insert(nums[i]);
help(ret, curVec, nums, visited);
curVec.pop_back();
visited.erase(nums[i]);
}
return;
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> ret;
vector<int> curVec;
unordered_set<int> visited;
help(ret, curVec, nums, visited);
return ret;
}
};
47. Permutations II 也是按照以上的思路去做。
但是又有一些不同,排列的结果要去重复的。
为何会有重复的那?
比如这个例子: {1, 1, 3}
我们还是按照之前的想法来做:
第一步,每个元素都作为排列组合的第一个元素:
{1}
{1}
{3}
第二步, 把剩下的没有访问的元素插入到排列组合里去。
{1, 1}
{1, 3}
{1, 1} - array[1]=1 排在前头, array[0] = 1排在后面
{1, 3}
{3, 1}array[0]=1 插入
{3, 1}array[1] = 1插入
从第二步开始就已经有重复的了,红色的都是重复的组合。
那么如何才能去掉重复的1 那。
这个才是这道题的关键。
分析下哦。红色的这3个组合,都是有个规律哦
array[1] 先于array[0] 被访问到并放到组合里。
我们就可以用这个来去重。
当有多个重复的数字时,
必须顺序的访问这些重复的数字,比如{1,1,3}。 必须先访问第一个1, 才能访问第二个1.
如果先访问第二个1 ,就算违规。
class Solution {
public:
void help(vector<vector<int>> &ret, vector<int>& curPermute, vector<int>& nums, unordered_set<int> &visitedNum)
{
if(curPermute.size() == nums.size()) {
ret.push_back(curPermute);
return;
}
for(int i =0;i<nums.size();i++) {
if(visitedNum.count(i) ==1)
continue;
if(i != 0 && nums[i] == nums[i-1] &&visitedNum.count(i-1) ==0 )
continue;
curPermute.push_back(nums[i]);
visitedNum.insert(i);
help(ret, curPermute, nums, visitedNum);
visitedNum.erase(i);
curPermute.pop_back();
}
return;
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ret;
vector<int> curPermute;
unordered_set<int> visitedNum;
sort(nums.begin(), nums.end());
help(ret, curPermute, nums, visitedNum);
return ret;
}