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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 回溯算法总结 -> 正文阅读

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

1、回溯算法介绍

参考:代码随想录
1. 定义
回溯算法是一种搜索算法,回溯是递归的副产品,只要有递归就有回溯,回溯函数就是递归函数,对于回溯的优化就是剪枝
回溯是在集合中递归搜索,回溯问题可以抽象为树形结构,集合的大小构成了树的宽度(for循环),递归的深度构成了数的深度
在这里插入图片描述

2. 可解决的问题

  • 组合问题:n个数中按一定规则找出k个数的集合
  • 排列问题:n个数中按一定规则全排列
  • 切割问题:一个字符串按一定规则切割
  • 子集问题:n个数的集合中符合条件的子集
  • 棋盘问题:n皇后,数独

3. 回溯的模板

void backreacking(参数) {
        if (终止条件) {
            存放结果;
            return;
        }
        for (选择:本层集合元素(树中节点孩子的数量就是结合的大小)) {
            处理节点;
            backreacking(路径,选择列表);//递归函数
            回溯,撤销处理结果;
        }
    }

2、组合问题

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。1 <= n <= 20;1 <= k <= n

示例 1:

输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
组合问题抽象为树形结构:
在这里插入图片描述
代码:

public class combine {
    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> res = new ArrayList<>();
        backtracking(n, k, 1, new ArrayList<Integer>(), res);
        return res;
    }

    /**
     * 回溯函数/递归函数
     * @param n 数的范围是 1-n
     * @param k 求k个数的组合
     * @param startIndex for循环每次从startIndex开始遍历 题目要求从1开始
     * @param path 存放取到的节点i
     * @param res 返回值
     */
    void backtracking(int n, int k, int startIndex, List<Integer> path, List<List<Integer>> res) {
        if (path.size() == k) {//此时path存放的数刚好是需要的组合
            res.add(new ArrayList<>(path));//加入到res的List中进行返回
            return;
        }
        //处理节点
        for (int i = startIndex; i <= n; i ++) {
            path.add(i);//处理节点
            backtracking(n, k, i + 1, path, res);//递归
            path.remove(path.size() - 1);//回溯,撤销处理的节点
        }
    }
 }

对回溯算法进行剪枝优化,效率会提升很多,一下使用leetcode的77题组合进行的测试结果:

  • 不用剪枝:
    在这里插入图片描述
  • 使用剪枝:
    在这里插入图片描述
    剪枝的树形结构:
    在这里插入图片描述
    当n=4,k=4时,第一层for循环,从元素2开始的遍历没有意义;第二层for循环,从元素3开始的遍历没意义了
    优化过程:
  • 已经选择的元素个数:path.size()
  • 还需要的元素个数:k - path.size()
  • 集合n中至少从位置:n - (k - path.size()) + 1开始遍历 (+1是因为需要包括起始位置)

优化后的代码:

	//剪枝优化
    void backtracking2(int n, int k, int startIndex, List<Integer> path, List<List<Integer>> res) {
        if (path.size() == k) {//此时path存放的数刚好是需要的组合
            res.add(new ArrayList<>(path));//加入到res的List中进行返回
            return;
        }
        //处理节点
        for (int i = startIndex; i <= n - (k - path.size()) + 1; i ++) {
            path.add(i);//处理节点
            backtracking(n, k, i + 1, path, res);//递归
            path.remove(path.size() - 1);//回溯,撤销处理的节点
        }
    }

注意:剪枝的思路就是for循环遍历时,n的范围

未完待续…

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:39:43  更:2022-03-03 16:42: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 15:38:05-

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