【LeetCode】47. Permutations II(C++)
阿新 • • 發佈:2018-12-02
地址:https://leetcode.com/problems/permutations-ii/
題目:
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example:
理解:
和permutation的區別就是需要考慮重複的數字會導致重複的結果。
實現1:
來源:Really easy Java solution, much easier than the solutions with very high vote
這種實現就是在permutation的基礎上修改。加了一個判斷條件。
條件的解釋應當是:保證第一次加入第一個元素後,可以加入後面的元素。一旦加入的第一個元素被彈出,不會把後面的相同元素再加進去,因為結果和上面是相同的。(把這些元素當作一個集體,要麼按順序依次加入,要麼都不加入)
class Solution { public: vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> res; vector<int> curr; vector<bool> flags(nums.size(), false); sort(nums.begin(), nums.end()); backtracking(nums, res, curr, flags); return res; } void backtracking(vector<int>& nums, vector<vector<int>>& res, vector<int>& curr, vector<bool>& flags) { if (nums.size() == curr.size()) { res.push_back(curr); } else { for (int i = 0; i < nums.size(); ++i) { if (flags[i]) continue; if (i != 0 && nums[i] == nums[i - 1] && !flags[i - 1]) continue; curr.push_back(nums[i]); flags[i] = true; backtracking(nums, res, curr, flags); flags[i] = false; curr.pop_back(); } } } };
實現2:
個人感覺這種更直觀一些,就是把nums存在一個map中,如果某個元素還有就新增並遞迴呼叫,否則不新增。
class Solution { public: vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> res; vector<int> curr; unordered_map<int, int> m; for (int num : nums) { m[num]++; } backtracking(m, res, curr); return res; } void backtracking(unordered_map<int,int>& m, vector<vector<int>>& res, vector<int>& curr) { bool flag = false; for (auto &iter : m) { if (iter.second != 0) { --iter.second; curr.push_back(iter.first); flag = true; backtracking(m, res, curr); curr.pop_back(); ++iter.second; } } if (!flag) res.push_back(curr); } };
實現3:
不是很理解這種實現。。
先存一下吧。本質應該還是為了避免把重複的加入。
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>> res;
backtracking(nums, res, 0);
return res;
}
void backtracking(vector<int> nums, vector<vector<int>>& res, int begin) {
if (begin == nums.size()-1) {
res.push_back(nums);
}
else {
for (int i = begin; i < nums.size(); ++i) {
if (i != begin&&nums[i] == nums[begin]) continue;
swap(nums[begin], nums[i]);
backtracking(nums, res, begin + 1);
}
}
}
};
實現4:
這種方式比較直觀,使用set避免了重複的加入。
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
backtracking(nums, res, 0);
return res;
}
void backtracking(vector<int>& nums, vector<vector<int>>& res, int begin) {
if (begin >= nums.size()) {
res.push_back(nums);
}
else {
unordered_set<int> s;
for (int i = begin; i < nums.size(); ++i) {
if (s.count(nums[i])) continue;
s.insert(nums[i]);
swap(nums[begin], nums[i]);
backtracking(nums, res, begin + 1);
swap(nums[begin],nums[i]);
}
}
}
};