C++回溯算法中的全排列问题分析探讨

 更新时间:2023年03月15日 09:06:01   作者:清风何渡  
递归中遇到一个问题全排列的问题,我看见回溯特别神奇,特此记录一下。对比一下深度优先搜索与广度优先搜索,个人感觉这里的回溯像是一种递归树中的深度优先搜索的算法,他不断构造往下延伸的深度,使其达到完全编列

一、全排列

全排列的特点就是:解放了index(每次遍历都从0开始),但是解放index的同时,又捆绑了used数组,记录已经出现过的元素

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
    int used[7]={0};
    void backtracking(vector<int>& nums){
        if(path.size()==nums.size()){
            result.push_back(path);
            return;
        }
        for(int i=0;i<nums.size();i++){
            if(used[i]==1)
                continue;
            path.push_back(nums[i]);
            used[i]=1;
            backtracking(nums);
            used[i]=0;
            path.pop_back();
        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        backtracking(nums);
        return result;
    }
};

二、全排列II

本题与全排列唯一不同在于需要去重这题与上一题唯一区别在于输入样例为可重复序列,且要求输出样例不重复

对于全排列问题,模板是设置used数组,只有used[i]==0时,才能选择该元素

对于去重问题,模板是先对nums排序,再判断nums[i]与nums[i-1]是否相等

根据全排列问题模板,设置used数组,只有used[i]==0时才可以选择

根据去重模板,先对nums排序,再判断nums[i]与nums[i-1]是否相等

但是全排列的去重没那么简单,因为全排列i是从0开始遍历,因此还要记录同一层当前已经访问到哪儿了,同一层不可以重复,但是同一树枝可以重复

但是不必再设置index,因为used数组可以兼任这个功能

如果used[i-1]==1,说明在同一个树枝访问过nums[i-1],同一树枝可以重复

如果used[i-1]==0,说明在同一层访问过nums[i-1],同一层不可以重复

很绕~

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
    int used[9]={0};
    void backtracking(vector<int>& nums){
        if(path.size()==nums.size()){
            result.push_back(path);
            return;
        }
        for(int i=0;i<nums.size();i++){
            if(i>0&&nums[i]==nums[i-1]&&used[i-1]==0)
                continue;
            if(used[i]==0){
                path.push_back(nums[i]);
                used[i]=1;
                backtracking(nums);
                used[i]=0;
                path.pop_back();
            }
        }
    }
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        backtracking(nums);
        return result;
    }   
};

到此这篇关于C++回溯算法中的全排列问题分析探讨的文章就介绍到这了,更多相关C++回溯算法全排列内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中的类扩展之继承和组合详解

    C++中的类扩展之继承和组合详解

    在C++中,类扩展可以通过继承、组合和装饰模式实现。继承可以实现对已有类的修改和扩展,组合可以增加新的功能,装饰模式则能够在不改变原类的情况下为其添加新的功能。这些技术在C++程序设计中应用广泛,提高了程序的可扩展性和可维护性
    2023-04-04
  • Qt中QPainter与坐标的使用

    Qt中QPainter与坐标的使用

    本文主要介绍了Qt中QPainter与坐标的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • 类成员函数的重载、覆盖与隐藏之间的区别总结

    类成员函数的重载、覆盖与隐藏之间的区别总结

    以下是对类成员函数的重载、覆盖与隐藏之间的区别进行了详细的总结分析,需要的朋友可以过来参考下。希望对大家有所帮助
    2013-10-10
  • C语言二维数组应用实现扫雷游戏

    C语言二维数组应用实现扫雷游戏

    这篇文章主要为大家详细介绍了C语言二维数组应用实现扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C++命名空间和缺省参数介绍

    C++命名空间和缺省参数介绍

    这篇文章主要介绍了C++命名空间和缺省参数,使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的,缺省参数是声明或定义函数时为函数的参数指定一个默认值,更多详细内容需要的小伙伴可以参考下面文章内容
    2022-01-01
  • 一波二叉树遍历问题的C++解答实例分享

    一波二叉树遍历问题的C++解答实例分享

    这篇文章主要介绍了一波二叉树遍历问题的C++解答实例分享,包括节点打印和转换为镜像等问题的解答,需要的朋友可以参考下
    2016-02-02
  • c语言中unsigned修饰符的使用

    c语言中unsigned修饰符的使用

    在C语言中,unsigned是一种无符号整数修饰符,本文主要介绍了c语言中unsigned修饰符的使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • C++中的继承方式与菱形继承解析

    C++中的继承方式与菱形继承解析

    这篇文章主要介绍了C++中的继承方式与菱形继承解析,继承是类和类之间的关系,是代码复用的重要手段,允许在保持原有类结构的基础上进行扩展,创建的新类与原有的类类似,只是多了几个成员变量和成员函数,需要的朋友可以参考下
    2023-08-08
  • C语言 奇偶排序算法详解及实例代码

    C语言 奇偶排序算法详解及实例代码

    这篇文章主要介绍了C语言 奇偶排序算法详解及实例代码的相关资料,需要的朋友可以参考下
    2016-11-11
  • C++实现折半插入排序(BinaryInsertSort)

    C++实现折半插入排序(BinaryInsertSort)

    这篇文章主要为大家详细介绍了C++实现折半插入排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04

最新评论