IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 回溯算法复习总结 -> 正文阅读

[数据结构与算法]回溯算法复习总结

敲响警钟之回溯算法真的很重要ballball了看看他

首先要明白所谓的回溯算法其实本质上就是递归的衍生,其实就是dfs

看一下回溯算法的模板

void backtracking(参数待定){
	if(设置终止条件){
		//设置所谓的终止条件,就是设置一个条件,当判断已经到达叶子结点之后应该进行如何的操作.
		xx.add();
		return;
	}
	for(){
		//这个for也是经典,会在这里遍历剩余集合的节点,有什么节点我们可以看着来
	}
}

切记,一整个回溯的算法,或者叫dfs算法,更像是一颗数的结构。在对于树做一个暴力遍历,求出每一种情况,然后进行求解。

77.组合

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

  1. 说明了返回的值是K个数的组合。那么所谓终止的条件,就是所谓的叶子结点,它的条件就是这个组合的长度达到了K。
  2. 这个是组合,并不是排序。所以我们开始规定不能有重复元素
class Solution {
    List<Integer> path = new LinkedList();//定义路径长度
    List<List<Integer>> res = new LinkedList();//设定返回值
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n,k,1);
        return res;
    }

    public void backtracking(int n,int k,int startindex){
        if(path.size() == k){
            //终止条件就是Path的路径长度,其实在这用startindex就去重了,但是对于去重的这个理念我理解的还是不太ok
            res.add(new LinkedList(path));
            return;
        }

        //对于迭代循环
        for(int i = startindex;i<=n;i++){
            path.add(i);
            backtracking(n,k,i+1);
            path.remove(path.size()-1);
        } 
    }
}

一个基础的回溯算法写好了

这个时候我们假设一种情况也就是 n=4 k=4的时候。这个时候明显只有一种排列情况也就是[1,2,3,4]

在这里插入图片描述
核心点是,你后期的元素不够支撑。比如第一次取3,后面还能取1,但是需要的元素是3个,只能有两个元素给你用,当然不够。在这个地方就能进行剪枝

if((n-startindex+1) < k-path.size()) return;

综上,加入这一条语句。

17 电话号码的组合方式
这题还算简单pass

40 组合总数2

这题的大体思路还是相同的,但是在去重这一点很重要。这题的去重思路真的,一开始我的脑子里只有,先把结果查出来,然后对于结果去重这一个思路。
但是现在给出的思路是,纵向的代表同一个组合中的元素,横向的代表的是不同组合中的元素。纵向的是可以重复的,而横向的是不可以的。

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        if(candidates == null || candidates.length==0) return res;
        Arrays.sort(candidates);
        visited = new boolean[candidates.length];
        
        backtracking(candidates,target,0);
        return res;
    }

    public void backtracking(int[] candidates,int target,int startindex){
        if(sum == target){
            //设置终止条件,相等的情况
            res.add(new LinkedList(path));
            return;
        }else if(sum > target) return;
    
        for(int i = startindex;i<candidates.length;i++){
            if(i>0 && candidates[i] == candidates[i-1] && !visited[i-1]) continue;
            visited[i] = true;
            sum += candidates[i];
            path.add(candidates[i]);
            backtracking(candidates,target,i+1);
            sum -= candidates[i];
            path.remove(path.size()-1);
            visited[i] = false;
        }
    }

39 组合总和

这道题很有意思,第一次做的时候做出来了,第二次做反而卡克了。
有一点在第一次没考虑竟然误打误撞做出来了。那就是对于相同元素的把握这个和分割的题目是一个道理。我一直在考虑怎么分割,怎么去做这个事情。其实情况已经包含了,我不知道如何去形容这种感觉很神奇自己体悟。

    int sum = 0;
    List<Integer> path = new LinkedList();
    List<List<Integer>> res = new LinkedList();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        if(candidates == null || candidates.length == 0) return res;
        backtracking(candidates,target,0);
        return res;
    }

    public void backtracking(int[] candidates,int target,int startindex){
        if(sum == target){
            //设置终止条件,终止条件就是sum=target呗
            res.add(new ArrayList(path));
            return;
        }else if(sum > target) return;

        for(int i = startindex;i<candidates.length;i++){
            sum += candidates[i];
            path.add(candidates[i]);
            backtracking(candidates,target,i);
            sum -= candidates[i];

            path.remove(path.size()-1);
        }
    }

40 组合3

这题的核心在于去重,这个回溯算法也是分为横向和纵向的。横向的表示这一层的节点,纵向的表示同一个排列中的节点。排完序后,你去去重就是同一层的节点不能使用第二次,看看代码中是如何保证的,十分精妙。

    int sum = 0;
    List<Integer> path = new LinkedList();  //记录路径
    List<List<Integer>> res = new LinkedList(); //返回值
    boolean[] visited;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        visited = new boolean[candidates.length];
        Arrays.sort(candidates);
         backtracking(candidates,target,0);
         return res;     
    }

    public void backtracking(int[] candidates,int target,int startindex){
        if(sum == target){
            res.add(new LinkedList(path));
            return;
        }else if(sum > target) return;

        for(int i = startindex;i<candidates.length;i++){
            if(i>0 && candidates[i]== candidates[i-1]){
                if(!visited[i-1]) continue;
            }
            visited[i] = true;
            sum += candidates[i];
            path.add(candidates[i]);
            backtracking(candidates,target,i+1);
            sum -= candidates[i];
            path.remove(path.size()-1);
            visited[i] = false;
        }
    }

46全排列

这个全排列的题目提醒了我两点

  1. visited[] 数组的用处是非常大的
  2. 如果每一次进入递归需要用到整个数组的时候,这个情况是不需要要startindex这个参数的
    List<List<Integer>> res = new LinkedList();
    List<Integer> path = new LinkedList();
    boolean[] visited;
    public List<List<Integer>> permute(int[] nums) {
        visited = new boolean[nums.length];
        backtracking(nums);
        return res;
    }
    public void backtracking(int[] nums){
        if(path.size() == nums.length){
            res.add(new LinkedList(path));
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(visited[i]) continue;
            visited[i] = true;
            path.add(nums[i]);
            backtracking(nums);
            visited[i] = false;
            path.remove(path.size()-1);
        }
    }
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:50:27  更:2022-03-15 22:51:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:57:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码