找到具有重复项的数组的排列。为什么在递归中传递值(C ++实现)

时间:2017-07-29 22:30:22

标签: algorithm recursion duplicates permutation

有多种方法可以找到具有重复项的整数数组的所有排列。在这里,我只讨论递归方法而不使用额外的" visited []"阵列。

正确的方法是:

    void helper(vector<vector<int>>& ans, vector<int> nums, int pos) {
        if(pos == nums.size()-1) {
            ans.push_back(nums);
            return;
        }
        for(int i = pos; i < nums.size(); i++) {
            if(i == pos || nums[i] != nums[pos]) {
                swap(nums[i], nums[pos]);
                helper(ans, nums, pos+1);
            }
        }
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        int n = nums.size();
        vector<vector<int>> ans;
        sort(nums.begin(), nums.end());
        helper(ans, nums, 0);
        return ans;
    }

我不太清楚为什么它将nums []作为副本传递给递归函数。所以我环顾四周geeks for geeks,它说&#34;想法是在第一个索引处修复第一个字符并递归调用其他后续索引&#34;。我以为我可以修复第一个字符,然后通过传递nums []作为参考来递归调用其他后续索引,并且&#34;交换回&#34;当递归完成时(如下所示)。但遗憾的是它没有用。

void helper(vector<vector<int>>& ans, vector<int>& nums, int pos) {
    if(pos == nums.size()-1) {
        ans.push_back(nums);
        return;
    }
    for(int i = pos; i < nums.size(); i++) {
        if(i == pos || nums[i] != nums[i-1]) {
            swap(nums[i], nums[pos]);
            helper(ans, nums, pos+1);
            swap(nums[i], nums[pos]);
        }
    }
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
    int n = nums.size();
    vector<vector<int>> ans;
    sort(nums.begin(), nums.end());
    helper(ans, nums, 0);
    return ans;
}

我想知道将nums []作为参考传递给递归时出了什么问题?为什么将nums []副本传递给递归是正确的?

1 个答案:

答案 0 :(得分:0)

我想我找到了原因。通过值传递并通过引用传递给出两个完全不同的算法。要明白这一点。让我们首先注意两个重要的观察结果:

  1. 我们做的第一件事是对数组进行排序,为什么?因为我们希望以“下一个排列”顺序访问所有排列,即123,132,213,231,312,321。这样就不会有重复。

  2. 下一次递归中的子问题也维护了sorted属性。让我们用一个例子来说明这一点。 输入nums = [1,2,2,3]将值传递给递归,其中pos = 0,

    i = 0:子问题是[2,2,3],

    i = 1:子问题是[1,2,3],

    i = 2:跳过,

    i = 3子问题是[1,2,2]。

  3. 此递归级别中的所有子问题都是SORTED。 但是如果[1,2,2,3]通过引用传递,则子问题不会被排序,因此您无法回复“下一个排列”方法来为您提供非重复的排列。

    如果您仍感到困惑,请花点时间阅读以下讨论: https://discuss.leetcode.com/topic/8831/a-simple-c-solution-in-only-20-lines/28?page=2