LeetCode第47.题之Permutations II

这题和上一题唯一的差别是数组多了重复的元素,所以我首先想到的是STL中计算排列组合关系的算法(这是我以前写的一篇博客)(该算法也适合上一题),具体思想见那篇博客,下面我直接给出C++代码:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        if (nums.size() == 0)
        {
            return res;
        }
        else if (nums.size() == 1)
        {
            res.push_back(nums);
            return res;
        }
        int n = nums.size();
        vector<int>::iterator pre_it= nums.end();   
        vector<int>::iterator it;
        for (;;)
        {
            pre_it= nums.end();
            --pre_it;
            it = pre_it;
            --pre_it;
            //从后往前找一对相邻的迭代器,前一个迭代器表示的数小于后一个迭代器表示的数
            while (pre_it != nums.begin() && *pre_it >= *it)
            {
                it = pre_it;
                -- pre_it;
            }
            //如果前一个迭代器表示的数小于后一个迭代器表示的数
            if(*pre_it < *it)
            {
                //从后往前找第一个大于pre_it表示的数(一定存在)
                vector<int>::iterator temp_it = nums.end();
                --temp_it;
                while (*temp_it <= *pre_it)
                    --temp_it;

                //交换这两个数,然后重新排序,即可得到下一个逆序
                iter_swap(pre_it, temp_it);
                sort(it, nums.end());
                res.push_back(nums);
            }
            //如果pre_it指向第一个元素,则将数组中的元素逆序然后保存下来,这是最后一个排列
            else
            {
                reverse(nums.begin(), nums.end());
                res.push_back(nums);
                return res;
            }               
        }
    }
};

int main()
{
    Solution s;
    vector<int> v;
    v.push_back(1);
    v.push_back(3);
    v.push_back(1);

    vector<vector<int>> res = s.permuteUnique(v);
    //输出结果
    for (vector<vector<int>>::iterator ita=res.begin();ita!=res.end();++ita)
    {
        for (vector<int>::iterator itb=ita->begin();itb!=ita->end();++itb)
        {
            cout<<*itb<<'\t';
        }
        cout<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值