凌云的博客

成功=工作+游戏+少说空话

LeetCode 算法题 47. Permutations II

分类:algorithm| 发布时间:2016-10-13 10:35:00


题目

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example,

[1,1,2] have the following unique permutations:

[
    [1,1,2],
    [1,2,1],
    [2,1,1]
]

题意

返回给出的数组的所有排列,数组中的数字有可能是重复的。

解法 1

跟上一题的解法类似,由于数字有可能重复,因此需要通过 set 来避免重复 swap 到相同的值。

class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> ret;
        permute(nums, 0, ret);
        return ret;
    }

    void permute(vector<int>& nums, int idx, vector<vector<int>>& ret) {
        if (idx == nums.size() - 1) {
            ret.push_back(nums);
            return;
        }

        unordered_set<int> sets;
        for (int i = idx; i < nums.size(); ++i) {
            if (sets.find(nums[i]) != sets.end()) continue;
            swap(nums[idx], nums[i]);
            sets.insert(nums[idx]);
            permute(nums, idx + 1, ret);
            swap(nums[i], nums[idx]);
        }
    }
};

解法 2

class Solution {
public:
    vector<vector<int> > permuteUnique(vector<int> &num) {
        vector<vector<int>> ret;
        vector<int> r;
        unordered_map<int, int> m;
        for (int i : num) {
            m[i]++;
        }

        permuteUnique(m, r, num.size(), ret);
        return ret;
    }

    void permuteUnique(unordered_map<int, int> &m, vector<int> &r, int remain, vector<vector<int>> &ret) {
        if (remain <= 0) {
            ret.push_back(r);
            return;
        }

        for (auto &p : m) {
            if (p.second <= 0) continue;
            p.second--;
            r.push_back(p.first);
            permuteUnique(m, r, remain - 1, ret);
            r.pop_back();
            p.second++;
        }
    }
};