当前位置: 首页 > news >正文

回溯算法 - 二叉树中和为某一值的路径 字符串的排列

目录

1.二叉树中和为某一值的路径

1.1 题目描述

1.2 回溯算法的一般步骤

1.3 解题思路

1.4 代码实现

2. 字符串的排列

2.1 题目描述

2.2 解题思路

2.3 代码实现


1.二叉树中和为某一值的路径

1.1 题目描述

输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为
expectNumber的所有路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n

 

1.2 回溯算法的一般步骤

1. 先添加值 (待选结果)

2. 再判定现有结果是否满足条件 (基于二叉树, 多叉树的穷举的过程, 在穷举的过程中, 要进行剪枝)

3. DFS (深度优先)

4. 回溯 (检测下一个)

1.3 解题思路

1.我们要明确从哪个节点开始.

2.深度优先遍历二叉树.

  • 遍历的过程中我们需要一个一维数组 (ArrayList<Integer>)来添加某条路径上的所有结点的值 (待选结果), 每添加一个值, 我们对应的 expectNumber 就对应减去该结点的值
  • 当该结点的左右子树都为空, 并且 expectNumber == 0 的时候, 此时我们需要一个二维数组 (ArrayList<ArrayList<Integer>>) 将其添加进去

1.4 代码实现

    public void FindPathDFS(TreeNode root, int expectNumber, ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list) {
        if(root == null) {
            return;
        }
        // 添加结果到待选结果中
        list.add(root.val);
        expectNumber -= root.val;
        // 条件判断, 剪枝 (合法判定)
        if(root.left == null && root.right == null && expectNumber == 0) {
            result.add(new ArrayList<Integer>(list));
        }

        // DFS
        FindPathDFS(root.left, expectNumber, result, list);
        FindPathDFS(root.right, expectNumber, result, list);

        // 回溯
        list.remove(list.size() - 1);
    }
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int expectNumber) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if(root == null) {
            return result;
        }
        ArrayList<Integer> list = new ArrayList<>();
        FindPathDFS(root, expectNumber, result, list);
        return result;
    }

2. 字符串的排列

2.1 题目描述

输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。

 示例1

输入:"ab"
返回值:["ab","ba"]
说明:返回["ba","ab"]也是正确的 

2.2 解题思路

上图中基于三叉树的一个穷举过程, 然后再剪枝, 就得到了符合要求的排列组合.

于是这道题的全排列问题, 就可以看做如下三叉树型状态:

基本思路:

  1. 分别以 a, b, c 作为排列组合的起始字符, 然后 bc, ac, ab 再分别排列组合 (循环 + 递归)
  2. 这三次循环, 每排列组合完其中一种情况, 就需要进行回溯, 然后继续下一次排列组合.
  3. 注意每次准备将待选结果添加进结果集之前, 需要做去重处理, 以免出现类似于 "aa" 排列组合两次的情况.

2.3 代码实现

    public void swap(char[] str, int start, int i) {
        char tmp = str[start];
        str[start] = str[i];
        str[i] = tmp;
    }
    public boolean isExist(ArrayList<String> result, char[] str) {
        return result.contains(String.valueOf(str));
    }
    public void PermutationHelper(char[] str, int start, ArrayList<String> result) {
        if (start == str.length - 1) {
            // 去重
            if (!isExist(result, str)) {
                result.add(new String(str));
            }
            return;
        }
        for (int i = start; i < str.length; i++) {
            swap(str, start, i); // 以 i 对应的字符作为开始
            PermutationHelper(str, start + 1, result); // [i+ 1, str.length- 1] 排列组合
            swap(str, start, i); // 回溯
        }
    }
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> list =  new ArrayList<>();
        if (str == null) {
            return list;
        }
        char[] ch = str.toCharArray();
        PermutationHelper(ch, 0, list);
        return list;
    }

相关文章:

  • 纯C实现的贪吃蛇(无EasyX,详解)
  • JAVA计算机毕业设计SUNHome家政服务管理平台Mybatis+系统+数据库+调试部署
  • 【项目管理】Java离线版语音识别-语音转文字
  • HTML5标签+基础特性
  • git的相关操作
  • ES6--》读懂JS中—Class类
  • 机器学习笔记(三)
  • 【Java 面试题】经典 Java 面试题 200 问(下)
  • 瑞吉外卖之 redis优化缓存
  • [JavaWeb]—前端篇
  • 机器学习感知机原理及python代码实现
  • js 对象
  • 图解Redis 记录
  • 网络安全的行业黑话 ——防守篇之软硬件
  • 使用 CubeMX 配置 RCC 时钟
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • [Vue CLI 3] 配置解析之 css.extract
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • AHK 中 = 和 == 等比较运算符的用法
  • ESLint简单操作
  • Golang-长连接-状态推送
  • js操作时间(持续更新)
  • node学习系列之简单文件上传
  • PAT A1050
  • Puppeteer:浏览器控制器
  • Travix是如何部署应用程序到Kubernetes上的
  • vue自定义指令实现v-tap插件
  • 爱情 北京女病人
  • 大整数乘法-表格法
  • 仿天猫超市收藏抛物线动画工具库
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 目录与文件属性:编写ls
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 如何优雅地使用 Sublime Text
  • 提醒我喝水chrome插件开发指南
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 写代码的正确姿势
  • 用jQuery怎么做到前后端分离
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • #mysql 8.0 踩坑日记
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (6)添加vue-cookie
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (汇总)os模块以及shutil模块对文件的操作
  • (学习日记)2024.02.29:UCOSIII第二节
  • (转)socket Aio demo
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (转载)hibernate缓存
  • .NET Core 2.1路线图
  • .net core 控制台应用程序读取配置文件app.config
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .Net 高效开发之不可错过的实用工具