47. Permutations II(全排列 II)解法(C++ & 注释)

1. 题目描述

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

题目链接:中文题目英文题目

2. 递归 & 序号插入(Recursion & Insert by Index)

2.1 解题思路

这题和46. Permutations几乎是一样,只是这里可能会有重复的组合,那问题就简单了,我们还是沿用上题的思路,只是需要额外去除下重复的组合,这里应用了set的特性:set里面的元素都是唯一不重复的,最后拷贝set的内容到答案数组里面就OK啦。

2.2 实例代码

class Solution {
    vector<vector<int>> ans;
    vector<bool>* ifUsed = nullptr; // 这里使用了指针动态分配内存,但使用起来比较麻烦,大家可以自己换一种简单的方式存储bool数组
    vector<int> temp;
    set<vector<int>> ansPre;

    // 1. 递归:recursionMethodUsingSwap和recursionMethodUsingBool,二选一即可
    void recursionMethodUsingSwap(vector<int>& nums, int cur) {
        if (cur == nums.size()) { ansPre.insert(nums); return; }
        for (int i = cur; i < nums.size(); i++) {
            swap(nums[cur], nums[i]);
            recursionMethodUsingSwap(nums, cur + 1);
            swap(nums[cur], nums[i]);
        }
    }

    void recursionMethodUsingBool(vector<int>& nums) {
        if (temp.size() == nums.size()) { ansPre.insert(temp); return; }
        for (int i = 0; i < nums.size(); i++) {
            if (!(*ifUsed)[i]) {
                temp.push_back(nums[i]);
                (*ifUsed)[i] = true;
                recursionMethodUsingBool(nums);
                temp.pop_back();
                (*ifUsed)[i] = false;
            }
        }
    }

    // 2. 迭代:按序号插入元素
    void insertElements(vector<int>& nums) {
        if (!nums.size()) return;
        this->ansPre.insert({ nums[0] });
        for (int i = 1; i < nums.size(); i++) {
            set<vector<int>> ans1;
            for (const vector<int>& num : ansPre) {
                for (int j = 0; j <= num.size(); j++) {
                    vector<int> arr = num;
                    arr.insert(arr.begin() + j, nums[i]);
                    ans1.insert(arr);
                }
            }

            ansPre = ans1;
        }
    }

public:
    ~Solution() { delete(this->ifUsed); }

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        // 1. recursion
        // recursionMethodUsingSwap(nums, 0);
        /*this->ifUsed = new vector<bool>(nums.size(), false);
        recursionMethodUsingBool(nums);*/

        // 2. iteration
        insertElements(nums);

        for (const vector<int>& v : this->ansPre) ans.push_back(v);

        return this->ans;
    }
};
展开阅读全文

Windows版YOLOv4目标检测实战:训练自己的数据集

04-26
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值