46. 全排列
这题和之前做的剑指offer上的字符串全排列。一样。
分析[1]:如果原始要排列的数组顺序为1、2、3、4,现在只要分别交换1、2,1、3,1、4然后对剩下的3个元素进行递归的排列。
自己的code:100%
class Solution {
public:
vector<vector<int>>res;
void helper(vector<int>& nums, int start)
{
if (start == (nums.size() - 1))
{
res.push_back(nums);
return;
}
if (start > nums.size() - 1)return;
for (int i = start; i < nums.size(); i++)
{
swap(nums[i], nums[start]);
helper(nums, start + 1);
swap(nums[i], nums[start]);
}
}
vector<vector<int>> permute(vector<int>& nums) {
helper(nums, 0);
return res;
}
};
47. 全排列II
给定一个可包含重复数字的序列,返回所有不重复的全排列。
这题让我想起之前刷的那道组合总和II
添加语句比46,if (i != start&&nums[i] == nums[i - 1])continue;
和sort
之后会发现还是会有重复的,例如0,0,0,1,9。
虽然避免了00019在开头重复,但是不可避免在后面重复91000.
这时采用set.
c++ code 99.6%:
class Solution {
//给定一个可包含重复数字的序列
public:
set<vector<int>>res;
void helper(vector<int>& nums, int start)
{
if (start == (nums.size() - 1))
{
res.insert(nums);
return;
}
if (start > nums.size() - 1)return;
for (int i = start; i < nums.size(); i++)
{
if (i != start&&nums[i] == nums[i - 1])continue;
swap(nums[i], nums[start]);
helper(nums, start + 1);
swap(nums[i], nums[start]);
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
helper(nums, 0);
return vector<vector<int>>(res.begin(),res.end());
}
};
方法二:不用set,
分析:每次for循环中找,level深度到了就ok,
借助一个visit辅助数组和out临时存储
- 有一处
if (i > 0 && nums[i] == nums[i - 1] && !visit[i - 1])continue;
很奇怪!if (i > 0 && nums[i] == nums[i - 1] && visit[i - 1])continue;
击败36%, 也可以通过就是慢点。 - 但是,不管有没有访问即
if (i > 0 && nums[i] == nums[i - 1])continue;
,只要前后相等就跳过。这是不可行的。 - 解释说哪个更节省时间(00019), !visit[i - 1]情况下是相对第一层树就开始剪枝了,所以更节省时间。第一个0在out是第一个,那么避免第二0在out中是一个。那么在 visit[i - 1]情况下通过是因为第一个0加进去之后第二个0加不进去,只能第二个0开始加进去第一个0才能接着加进去,这样本来可以很快完成的,现在需要更多次操作才能完成。但是上述不可行操作是完成不了把所有0加进去的。
- 最后仅仅是个人理解,带一个例子走一遍好理解。
下面code 99.6%
class Solution {
//给定一个可包含重复数字的序列
//借助一个visit辅助数组和out临时存储
public:
vector<vector<int>>res;
vector<int>out;
void helper(vector<int>& nums, vector<int>& visit, int level)
{
if (level >= nums.size())
{
res.push_back(out);
return;
}
for (int i = 0; i < nums.size(); i++)
{
if (!visit[i])
{
if (i > 0 && nums[i] == nums[i - 1] && !visit[i - 1])continue;
out.push_back(nums[i]);
visit[i] = 1;
helper(nums, visit, level + 1);
out.pop_back();
visit[i] = 0;
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int>visit(nums.size(), 0);
helper(nums, visit,0);
return res;
}
};
[1]https://blog.youkuaiyun.com/u013309870/article/details/68941284