美文网首页
BM56 有重复项数字的全排列

BM56 有重复项数字的全排列

作者: help_youself | 来源:发表于2022-07-07 11:47 被阅读0次
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
    vector<vector<int> > permuteUnique(vector<int> &num) {
        std::sort(num.begin(),num.end());
        vector<vector<int> > res;
        int n=num.size();
        std::vector<int> path;
        std::vector<bool> visit(n,0);
        if(0!=n){
            conv(num,res,path,visit);
        }
        return res;
    }
    void conv(std::vector<int>&num,std::vector<std::vector<int>>& res,
              std::vector<int>&path,std::vector<bool>& visit){
        if(path.size()==num.size()){
            res.push_back(path);
            return;
        }
        for(int i=0;i<num.size();i++){
            if(visit[i]) continue;
            if(i&&(num[i]==num[i-1])&&!visit[i-1]){
                continue;
            }
            visit[i]=true;
            path.push_back(num[i]);
            conv(num,res,path,visit);
            visit[i]=false;
            path.pop_back();

        }
    }

};
int main(){
    std::vector<int> data={1,1,3};
    Solution so;
    vector<vector<int> > ret=so.permuteUnique(data);
    int n=ret.size();
    for(int i=0;i<n;i++){
        int l=ret[i].size();
        for(int j=0;j<l;j++){
            std::cout<<ret[i].at(j)<<" ";
        }
        std::cout<<std::endl;
    }
    return 0;
}

 这里实现的代码,基本上是从博客[1]中抄袭的。这里主要解释下下面if语句中的判断条件是怎么起到筛选的作用的(筛除重复的组合)。尤其是!visit[i-1]的条件有点难以理解。

 if(i&&(num[i]==num[i-1])&&!visit[i-1]){
        continue;
 }

 假设测试序列为data={1,1,3},索引序号i为0,1,2。索引序号i的全排列为:

索引序号排列i,j,k 对应值data[i], data[j], data[k] if满足,执行continue
0,1,2 1,1,3 no
0,2,1 1,3,1 no
1,0,2 1,1,3 yes
1,2,0 1,3,1 yes
2,0,1 3,1,1 no
2,1,0 3,1,1 yes

 在执行for循环的过程中,没有被if条件过滤的数值组合,被存储到res.push_back(path)。针对data[i], data[j], data[k]序列重复的场景,可以观察if条件是否滤除的规律:

重复值对应索引序号按照升序排列的,数字排列留存。否则,就会被if条件滤除,执行continue.

 由于data[0]=data[1],索引序号(0,1,2)和索引序号(1,0,2)对应的值排列是相同的。索引序号(0,1,2)对应的排列,可以留下,而(1,0,2)对应的排列需要筛除。需要筛除的排列data[1], data[0], data[2],序号1在前,0在后面,可以认为是乱序的。
 在for循环中,通过visit[i]标记节点num[i]是否访问。当num[i]==num[i-1],说明数据重复,!visit[i-1]说明i-1对应的节点未被访问,假设continue语句不存在,则最终形成的序列B为:...data[i].....data[i-1]...。通过交换data[i]和data[i-1],可以得到序列A:...data[i-1].....data[i]...。
序列A和序列B是等价的。B序列对应的重复值的索引位置,是按照升序排列的。而if中的判定条件,就可以筛除序列A。

Reference:
[1]全排列(有重复项数字和无重复数字)

相关文章

  • BM56 有重复项数字的全排列

     这里实现的代码,基本上是从博客[1]中抄袭的。这里主要解释下下面if语句中的判断条件是怎么起到筛选的作用的(筛除...

  • 递归与回溯:python列表排列问题

    给定一个 没有重复 数字的序列,返回其所有可能的全排列。 给定一个有重复 数字的序列,返回其所有可能的全排列且不重复

  • Leetcode.46.Permutations

    题目 给定一个没有重复数字的数字序列, 输出这写数字的全排列组合. 思路 这种全排列的问题最直接的思路就是递归. ...

  • 【leetcode】全排列

    【leetcode】全排列 题目: 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1...

  • 排列类算法问题大总结

    全排列 带重复元素的排列 下一个排列 上一个排列 第 k 个排列 排列序号 排列序号II 全排列 给定一个数字列表...

  • 子集、全排列、第k个排列

    子集输出 全排列输出 存在重复数字的全排列 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。 按大...

  • LeetCode 第 47 题:全排列 II

    传送门:47. 全排列 II。 给定一个可包含重复数字的序列,返回所有不重复的全排列。示例:输入: [1,1,2]...

  • LeetCode-46-全排列

    LeetCode-46-全排列 题目 给定一个没有重复数字的序列,返回其所有可能的全排列。 示例: 输入: [1,...

  • 每周 ARTS 第 19 期

    1. Algorithm 46. 全排列(中等) 描述: 给定一个没有重复数字的序列,返回其所有可能的全排列。 示...

  • LeetCode:全排列

    46. 全排列 给定一个** 没有重复** 数字的序列,返回其所有可能的全排列。示例:输入: [1,2,3]输出:...

网友评论

      本文标题:BM56 有重复项数字的全排列

      本文链接:https://www.haomeiwen.com/subject/unoubrtx.html