【发布时间】:2015-11-10 08:51:31
【问题描述】:
解决以下问题作为算法难题。参考了一些类似的解决方案(并在下面发布其中一个),尝试过并且它们奏效了。问题是,对于“swap(num[i], num[k]);”这一行,我们如何确保我们总是可以交换到以前从未尝试过的数字(例如,假设我们在当前迭代中将 1 与 2 交换for 循环,那么以后我们有可能在相同级别/递归调用层的相同 for 循环的下一次迭代中将 2 换回 1)?我很困惑,因为我们通过引用传递 num,并且以后(较低级别/层)递归调用很可能会修改 num 的内容,这会导致我们已经评估过的数字交换回来。但是,我尝试过,它适用于我所有的测试用例。想知道下面的解决方案是 100% 正确,还是碰巧通过了我的测试用例? :)
这是我正在调试的详细问题陈述和代码,
给定一组可能包含重复的数字,返回所有可能的唯一排列。
例如, [1,1,2] 具有以下独特排列: [1,1,2]、[1,2,1] 和 [2,1,1]
class Solution {
public:
void recursion(vector<int> num, int i, int j, vector<vector<int> > &res) {
if (i == j-1) {
res.push_back(num);
return;
}
for (int k = i; k < j; k++) {
if (i != k && num[i] == num[k]) continue;
swap(num[i], num[k]);
recursion(num, i+1, j, res);
}
}
vector<vector<int> > permuteUnique(vector<int> &num) {
sort(num.begin(), num.end());
vector<vector<int> >res;
recursion(num, 0, num.size(), res);
return res;
}
};
提前致谢, 林
【问题讨论】:
-
num 不是通过引用传递给
recursion()- 每个调用都会获得一个全新的数字数组副本。 -
在我看来," if (i != k && num[i] == num[k]) continue; 行创建了很多重复检查,更简单的是 if (num[i] == 数字 [k]) 继续;会更好,因为该循环中的第一个遍历不会进入递归调用,而且 int j 参数始终是 num.size 所以为简单起见,您可能希望将其删除
-
@user1316208 没有
i!=k,第一次递归(没有任何改变/某些东西与自身交换)不会发生=>没有结果。i!=k是必需的。 -
@deviantfan 在我看来,结果将在 for 循环中进一步获得。但也许我错了
-
@user1316208 用 1 1 2 试试(手动,或代码,你喜欢什么)。不会有任何结果(但也许我也错了:))