数据结构(六)—— 二叉树(4)回溯

news/2024/10/20 18:59:04/

文章目录

  • 一、题
  • 1 257 二叉树的所有路径
    • 1.1 写法1
    • 1.2 写法2


一、题

1 257 二叉树的所有路径

1.1 写法1

递归+回溯:回溯是递归的副产品,只要有递归就会有回溯

首先考虑深度优先搜索;而题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
在这里插入图片描述
递归和回溯就是一家的,本题也需要回溯。

1、确定递归函数输入输出
要传入根节点,记录每一条路径的vector<int>&,和存放结果集的vector<string>&,这里递归不需要返回值,
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result)
2、确定递归终止条件
一般来说都是if(cur == NULL) return,但是本题要找到叶子节点,就开始结束的处理逻辑了(把路径放进result里)。
那么什么时候算是找到了叶子节点? 是当 cur不为空,其左右孩子都为空的时候,就找到叶子节点。

if (cur->left == NULL && cur->right == NULL) { // 遇到叶子节点string sPath;for (int i = 0; i < path.size() - 1; i++) { // 将path里记录的路径转为string格式sPath += to_string(path[i]);sPath += "->";}sPath += to_string(path[path.size() - 1]); // 记录最后一个节点(叶子节点)result.push_back(sPath); // 收集一个路径return;
}

3、确定单层递归逻辑
因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进path中。
path.push_back(cur->val);

然后是递归和回溯的过程,上面说过没有判断cur是否为空,那么在这里递归的时候,如果为空就不进行下一层递归了。
所以递归前要加上判断语句,下面要递归的节点是否为空,如下
if (cur->left) traversal(cur->left, path, result);
此时还没完,递归完,要做回溯啊,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点。

if (cur->left) {traversal(cur->left, path, result);path.pop_back(); // 回溯
}
if (cur->right) {traversal(cur->right, path, result);path.pop_back(); // 回溯
}

4、整合traversal()

class Solution {
private:void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {path.push_back(cur->val); // 中,中为什么写在这里,因为最后一个节点也要加入到path中 // 这才到了叶子节点if (cur->left == NULL && cur->right == NULL) {string sPath;for (int i = 0; i < path.size() - 1; i++) {sPath += to_string(path[i]);sPath += "->";}sPath += to_string(path[path.size() - 1]);result.push_back(sPath);return;}if (cur->left) { // 左 traversal(cur->left, path, result);path.pop_back(); // 回溯}if (cur->right) { // 右traversal(cur->right, path, result);path.pop_back(); // 回溯}}public:vector<string> binaryTreePaths(TreeNode* root) {vector<string> result;vector<int> path;if (root == NULL) return result;traversal(root, path, result);return result;}
};

1.2 写法2

1、确定输入输出
输入:节点、每条路径string、每条路径组成的vector<string>&
输出:空
void traversal(TreeNode* cur, string path, vector<string>& result)

注意:函数输出定义的是string,每次都是复制赋值,没使用引用,否则就无法做到回溯的效果。(这里涉及到C++语法知识)
2、确定退出条件

if (cur->left == NULL && cur->right == NULL) {result.push_back(path);return;
}

3、确定单层逻辑
中左右

path += to_string(cur->val); // 中
...  // 退出条件
if (cur->left) traversal(cur->left, path + "->", result); // 左
if (cur->right) traversal(cur->right, path + "->", result); // 右

4、整合

class Solution {
private:void traversal(TreeNode* cur, string path, vector<string>& result) {path += to_string(cur->val); // 中if (cur->left == NULL && cur->right == NULL) {result.push_back(path);return;}if (cur->left) traversal(cur->left, path + "->", result); // 左if (cur->right) traversal(cur->right, path + "->", result); // 右}public:vector<string> binaryTreePaths(TreeNode* root) {vector<string> result;string path;if (root == NULL) return result;traversal(root, path, result);return result;}
};

在哪儿回溯的?
如上代码貌似没有看到回溯的逻辑,其实不然,回溯就隐藏在traversal(cur->left, path + "->", result);中的 path + "->"。 每次函数调用完,path并没有加上"->",这就是回溯了。

使用如下代码可以更好的体会到回溯

if (cur->left) {path += "->";traversal(cur->left, path, result); // 左path.pop_back(); // 回溯 '>'path.pop_back(); // 回溯 '-'
}
if (cur->right) {path += "->";traversal(cur->right, path, result); // 右path.pop_back(); // 回溯 '>' path.pop_back(); //  回溯 '-' 
}

http://www.ppmy.cn/news/61368.html

相关文章

Docker安装常用软件-Nacos

一、单机部署 官方网站&#xff1a;什么是 Nacos 1、下载最新nacos镜像 docker pull nacos/nacos-server 2、新建映射文件夹 --nacos/conf/application.properties --nacos/logs --nacos/sql ①application文件 # # Copyright 1999-2021 Alibaba Group Holding Ltd. #…

Python机器学习入门 -- 支持向量机学习笔记

文章目录 前言一、支持向量机简介二、支持向量机的数学原理1. 距离解算2. 目标函数3. 约束下的优化求解4. 软间隔优化5. 核函数变换 三、Python实现支持向量机1. 惩罚力度对比2. 高斯核函数3. 非线性SVM 总结 前言 大部分传统的机器学习算法都可以实现分类任务&#xff0c;但这…

领先的项目协作管理软件OpenProject

本文软件由网友 不长到一百四誓不改名 推荐&#xff1b; 什么是 OpenProject &#xff1f; OpenProject 是一个开源、基于 Web 的项目管理系统&#xff0c;提供了免费的社区版和收费的企业版。OpenProject 拥有完善的文档&#xff0c;API&#xff0c;及丰富的功能&#xff0c;可…

CBCGPRibbon 界面控件文本刷新问题

在按钮等响应事件中&#xff0c;常常会加入多线程的操作&#xff0c;但是如果将按钮文本等刷新操作写入多线程会造成崩溃&#xff0c;因此我们需要采用消息机制的办法来实现&#xff0c;以下是实现的实例&#xff1a; #define WM_UPDATERIBBON_DATA WM_USER 1 afx_msg LRESU…

[实训] 实验1-SPI数据传输基础实验(下)

目录 五、实验测试数据表格记录 六、实验数据分析及处理 七、实验结论与感悟 五、实验测试数据表格记录 实验现象数码管显示见第四节图4.4&#xff0c;示波器测量结果见下列图片。 图5.1 RST、MOSI/MISO波形测量结果 图5.2 SCLK、MOSI/MISO波形测量结果 仅调整示波器波…

jsp网上拍卖管理系统统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 jsp网上拍卖管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&a…

(bfs无边权最短路)Catch That Cow

Problem - 2717 (hdu.edu.cn) 我的思路&#xff1a; 当时想的是dp&#xff0c;dfs&#xff08;深度优先做不了&#xff0c;求解要把所有可能性都遍历完&#xff0c;复杂度不合适&#xff09;啥的&#xff0c;完全没想到是bfs的最短路。 题解思路&#xff1a; 每次行动耗费1…

【前端面经】网络-Axios

简介 Axios是一种流行的JavaScript库&#xff0c;用于在浏览器中进行HTTP请求。它基于Promise API&#xff0c;使其非常易于使用和与其他库集成。Axios提供了许多功能&#xff0c;例如请求和响应拦截&#xff0c;自动转换JSON数据等等。在本篇博客中&#xff0c;我们将讨论Axi…