混淆排列计算的唯一性

时间:2015-11-10 08:51:31

标签: c++ algorithm

将下面的问题作为算法难题进行处理。提到了一些类似的解决方案(并在下面发布其中一个),试过并且他们工作了。问题是,对于“swap(num [i],num [k]);”这一行,我们如何确保我们总能交换到之前从未尝试过的数字(例如,假设我们在当前迭代中交换1和2)对于循环,那么以后我们可以在同一级别/递归调用层的循环的下一次迭代中将1替换为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;
    }
};
提前谢谢, 林

2 个答案:

答案 0 :(得分:3)

正如@notmyfriend在评论中所说,num实际上是复制了每个函数调用 所以现在归结为:

  • 在所有数组值中,选择一个作为第一个数组值并将其放在那里 在一个循环中为每个值一次,然后递归:
    • 在第一个之后的所有值中,选择一个作为第一个并将其放在那里......

...等等,结合检查过滤掉没有变化的掉期,即。过滤掉重复的。

如果num是真正的参考,它将不再有效(至少没有额外的步骤)。
例如。 1 1 2是一个简单的例子,它会给出结果:

112, 121, 211, 112, 121  

即。尽管检查有重复(可能还有) 是一些例子,其中也没有生成某些排列)。

关于评论:

默认情况下,C ++中的每个普通函数参数都被复制 (正常=没有明确的参考符号&#39;&amp;&#39;等) 也许你正在考虑C风格的数组:基本上,传递的是一个指针(第一个值)。指针被复制,但原始指针和复制指针都指向同一个内存位置。

虽然std::vector的目的是(也)包含一个数组,但该向量本身是一个单独的类对象(它包含一个指向某处值的指针)。类可以自己定义应该如何复制(使用复制构造函数) 从技术上讲,矢量类可以实现复制作为指针复制,然后它将传递整个矢量作为参考具有相同的效果;但C ++创建者想要保留复制语义,即。复制容器类应该制作一个包含所有重复值的真实副本 对于非复制,已有参考文献......

答案 1 :(得分:1)

您可以在下面找到用Java编写的解决方案。很抱歉没有提供C ++解决方案,我很长时间没有使用它。但语法类似。

解决方案正在使用回溯(https://en.wikipedia.org/wiki/Backtracking) 另外我使用hashset来检查唯一性,可能有一个解决方案不使用任何hashset类型的数据结构,因为我的解决方案是使用额外的内存来提供独特的解决方案。

示例输入和输出;

<iframe src="http://localhost:5601/#/dashboard/New-Dashboard?
embed&_g=(refreshInterval:(display:Off,pause:!f,section:0,value:0)
,time:(from:now-6M,mode:quick,to:now))&_a=(filters:!(),panels:!
((col:1,id:env,row:1,size_x:4,size_y:3,type:visualization),
(col:5,id:env-2,row:1,size_x:4,size_y:3,type:visualization),
(col:9,id:env-3,row:1,size_x:4,size_y:3,type:visualization)),
query:(query_string:(analyze_wildcard:!t,query:'*')),title:'New%20Dashboard')
" height="600" width="800" id="myframe"></iframe>

解决方案是;

input  :  [1, 1, 2]
output :  [1, 1, 2]
          [1, 2, 1]
          [2, 1, 1]