[leetcode] Permutations II

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], and [2,1,1].


http://www.cnblogs.com/TenosDoIt/p/3662644.html

 只是单纯判断两个位置是同一个数字,然后不swap是不行的。。因为如果要是有两个对数字一样呢。。比如[1, 1, 2, 2]

就费了。。只判断了一对数字。。

class Solution {
public:
    void dfs(vector<int> &num, int step, vector<vector<int> > &res) {
        if (step > num.size()-1) {
            res.push_back(num);
            return;
        }
        int i;
        for (i = step; i < num.size(); i++) {
            if (num[i] == num[step] && i!=step)   // 这样不行。。
                continue;
            swap(num[i], num[step]);
            dfs(num, step + 1, res);
            swap(num[i], num[step]);
        }
    }
    vector<vector<int> > permuteUnique(vector<int> &num) {
        vector<vector<int> > res;
        dfs(num, 0, res);
        return res;
    }
};

http://www.cnblogs.com/sooner/p/3264882.html

换种思维,对122,第一个数1与第二个数2交换得到212,然后考虑第一个数1与第三个数2交换,此时由于第三个数等于第二个数,所以第一个数不再与第三个数交换。再考虑212,它的第二个数与第三个数交换可以得到解决221。此时全排列生成完毕。

这样我们也得到了在全排列中去掉重复的规则——去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。用编程的话描述就是第i个数与第j个数交换时,要求[i,j)中没有与第j个数相等的数


class Solution {
public:
    bool noswap(vector<int> &num, int i, int step) {
        int j;
        for (j = step; j < i; j++) {
            if (num[i] == num[j])
                return true;
        }
        return false;
    }
    void dfs(vector<int> &num, int step, vector<vector<int> > &res) {
        if (step > num.size()-1) {
            res.push_back(num);
            return;
        }
        int i;
        for (i = step; i < num.size(); i++) {
            if (noswap(num, i, step))
                continue;
            swap(num[i], num[step]);
            dfs(num, step + 1, res);
            swap(num[i], num[step]);
        }
    }
    vector<vector<int> > permuteUnique(vector<int> &num) {
        vector<vector<int> > res;
        dfs(num, 0, res);
        return res;
    }
};



至此我们已经运用了递归与非递归的方法解决了全排列问题,总结一下就是:

1.全排列就是从第一个数字起每个数分别与它后面的数字交换。

2.去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。

3.全排列的非递归就是由后向前找替换数和替换点,然后由后向前找第一个比替换数大的数与替换数交换,最后颠倒替换点后的所有数据。






  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值