【算法】全排序I,全排序II-回溯算法中的树枝去重和树层去重理解

简介: 【算法】全排序I,全排序II-回溯算法中的树枝去重和树层去重理解

文章目录

先分析一下这道题目的区别,

首先46题题中要求是不含重复元素,所以我们在进行回溯的时候不需要对数据进行去重、

其次47题题中说明了含有重复元素,所以我们在进行回溯过程中需要对数据进行去重。那么我们怎么去重呢?

42682eb05cda40c29be66dca07241cbf.png05b00eec4cb44694b612de150e64ca8b.png

上面两道题我们使用传统的回溯写法很容易就可以写出来,但是对于47题难点是对数据进行去重,这里我们需要解释一下卡子哥自创的树枝去重和树层去重

我们用树化的思维去寻找符合条件的值,存在多个同一个数的时候,在同一个树枝上可以重复,对于同一层来说,如果再取这个数据就会出现重复,一般用一个used数据来表示,不太理解的话可以先记住,多做几道题就理解了。(我大概遇到五六道题就慢慢理解了)。


树层去重:

if(i>0 && num[i] == nums[i-1] && used[i-1] == false)


树枝去重:

if(i>0 && num[i] == nums[i-1] && used[i-1] == true)


这里我给出两道题的示例代码,仔细品一品吧。

全排序I

class Solution {
    List<List<Integer>>  list  = new ArrayList<>();
    LinkedList<Integer> list1 = new  LinkedList<>();
    boolean[] used;
    public List<List<Integer>> permute(int[] nums) {
        if(nums.length == 0){
            list.add(new ArrayList<>(list1));
            return list;
        }
        used = new boolean[nums.length];
        HiSir(nums);
        return list;
    }
    public void HiSir(int[] nums){
        if(list1.size() == nums.length){
            list.add(new ArrayList<>(list1));
            return;
        }
        for(int i = 0;i<nums.length;i++){
            if(used[i]){
                continue;
            }
            used[i] = true;
            list1.add(nums[i]);
            HiSir(nums);
            used[i] = false;
            list1.removeLast();
        }
    }
}


全排序II

class Solution {
    List<List<Integer>> list = new ArrayList<>();
    LinkedList<Integer> list1 = new LinkedList<>();
    boolean[] used;
    public List<List<Integer>> permuteUnique(int[] nums) {
        if(nums.length == 0){
            list.add(new ArrayList<>(list1));
            return list;
        }
        used = new boolean[nums.length];
        Arrays.fill(used,false);
        Arrays.sort(nums);
        HiSir(nums);
        return list;
    }
    public void HiSir(int[] nums){
        if(list1.size() == nums.length){
            list.add(new ArrayList<>(list1));
            return;
        }
        for(int i =0;i<nums.length;i++){
            if(i >0 && nums[i] == nums[i-1] && used[i-1] == false){
                continue;
            }
            if(used[i] == false){
                used[i] = true;
                list1.add(nums[i]);
                HiSir(nums);
                list1.removeLast();
                used[i] = false;
        }
    }
}
}


相关文章
|
9天前
|
算法 C++
【洛谷 P1223】排队接水(贪心算法+结构体排序)
该问题要求安排$n$个人的排队顺序以最小化平均等待时间。每个人接水需时$T_i$,解决方案是让接水时间短的人优先。给定$n\leq1000$和$t_i\leq10^6$,代码示例使用C++实现,通过排序使时间从小到大排列,然后计算平均等待时间。样例输入为10个人的时间数组,输出为优化后的排队顺序及平均等待时间(291.90)。
12 0
|
9天前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
17 4
|
4天前
|
存储 算法 Linux
【数据结构和算法】---二叉树(1)--树概念及结构
【数据结构和算法】---二叉树(1)--树概念及结构
10 0
|
9天前
|
算法 Java 机器人
Java数据结构与算法:AVL树
Java数据结构与算法:AVL树
|
6天前
|
机器学习/深度学习 人工智能 算法
回溯算法是怎样的
回溯算法,择优搜索:树的深搜+剪枝
|
7天前
|
机器学习/深度学习 算法
梯度提升树GBDT系列算法
在Boosting集成算法当中,我们逐一建立多个弱评估器(基本是决策树),并且下一个弱评估器的建立方式依赖于上一个弱评估器的评估结果,最终综合多个弱评估器的结果进行输出。
|
9天前
|
存储 算法 Python
python常用算法(5)——树,二叉树与AVL树(一)
python常用算法(5)——树,二叉树与AVL树
|
11天前
|
算法 数据可视化 Python
Python中的决策树算法探索
Python中的决策树算法探索
|
12天前
|
搜索推荐 算法
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
|
16天前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素