本文 https://github.com/youngyangyang04/leetcode-master 已经收录,里面还有leetcode刷题攻略、各个类型经典题目刷题顺序、思维导图,可以fork到自己仓库,有空看一看一定会有所收获,如果对你有帮助也给一个star支持一下吧!

昨天的总结篇中还在玩耍的你,该总结啦!(本周小结之二叉树),有两处问题需要说明一波。

求相同的树

还在玩耍的你,该总结啦!(本周小结之二叉树)中求100.相同的树的代码中,我笔误贴出了 求对称树的代码了,细心的同学应该都发现了。

那么如下我再给出求100. 相同的树 的代码,如下:

class Solution {
public:bool compare(TreeNode* tree1, TreeNode* tree2) {if (tree1 == NULL && tree2 != NULL) return false;else if (tree1 != NULL && tree2 == NULL) return false;else if (tree1 == NULL && tree2 == NULL) return true;else if (tree1->val != tree2->val) return false; // 注意这里我没有使用else// 此时就是:左右节点都不为空,且数值相同的情况// 此时才做递归,做下一层的判断bool compareLeft = compare(tree1->left, tree2->left);       // 左子树:左、 右子树:左bool compareRight = compare(tree1->right, tree2->right);    // 左子树:右、 右子树:右bool isSame = compareLeft && compareRight;                  // 左子树:中、 右子树:中(逻辑处理)return isSame;}bool isSameTree(TreeNode* p, TreeNode* q) {return compare(p, q);}
};

以上的代码相对于:二叉树:我对称么? 仅仅修改了变量的名字(为了符合判断相同树的语境)和 遍历的顺序。

大家应该会体会到:认清判断对称树本质之后, 对称树的代码 稍作修改 就可以直接用来AC 100.相同的树。

递归中隐藏着回溯

在二叉树:找我的所有路径?中我强调了本题其实是用到了回溯的,并且给出了第一个版本的代码,把回溯的过程充分的提现了出来。

如下的代码充分的体现出回溯:(257. 二叉树的所有路径)

class Solution {
private:void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {path.push_back(cur->val);// 这才到了叶子节点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;}
};

如下为精简之后的递归代码:(257. 二叉树的所有路径)

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) traversal(cur->left, path + "->", result); // 左  回溯就隐藏在这里

改成如下代码:

path += "->";
traversal(cur->left, path, result); // 左

即:


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

此时就没有回溯了,这个代码就是通过不了的了。

如果想把回溯加上,就要 在上面代码的基础上,加上回溯,就可以AC了。

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();
}

大家应该可以感受出来,如果把 path + "->"作为函数参数就是可以的,因为并有没有改变path的数值,执行完递归函数之后,path依然是之前的数值(相当于回溯了)

如果有点遗忘了,建议把这篇二叉树:找我的所有路径?在仔细看一下,然后再看这里的总结,相信会豁然开朗。

这里我尽量把逻辑的每一个细节都抠出来展现了,希望对大家有所帮助!

我是程序员Carl,利用工作之余重刷leetcode,更多精彩算法文章尽在:代码随想录,关注后,回复「Java」「C++」「python」「简历模板」等等,有我整理多年的学习资料,可以加我微信,备注「简单自我介绍」+「组队刷题」,拉你进入刷题群(无任何广告,纯个人分享),每天一道经典题目分析,我选的每一道题目都不是孤立的,而是由浅入深一脉相承的,如果跟住节奏每篇连续着看,定会融会贯通。

以下资料希望对你有帮助:

  • 学习资料以及我的开源项目
  • 我的B站视频:算法和编程语言的讲解
  • leetcode刷题攻略
  • 程序员应该如何写简历(附简历模板)
  • 一线互联网公司技术面试的流程以及注意事项
  • C++面试&C++学习指南知识点整理

如果感觉题解对你有帮助,不要吝啬给一个

二叉树:以为使用了递归,其实还隐藏着回溯相关推荐

  1. 消除左递归c++代码_「leetcode」129. 求根到叶子节点数字之和【递归中隐藏着回溯】详解...

    链接 https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/ 思路 本题和113.路径总和II是类似的思路,做完这道题,可以顺便把113. ...

  2. 二叉树 2.0 -- 非递归遍历

    二叉树递归遍历存在的问题 如果我们的二叉树只有左子树,而且树的高度还很深的时候,这个时候递归调用遍历的时候,栈帧空间开辟的较大,很可能造成栈溢出.但是我们一个程序中,为堆分配的空间要比栈大的多,这个时 ...

  3. 二叉树的几种递归和非递归式遍历:

    二叉树的几种递归和非递归式遍历: 1 #include <fstream> 2 #include <iostream> 3 4 using namespace std; 5 6 ...

  4. 线索二叉树中序非递归线索化以及递归线索化构建和遍历算法

    引文 大部分教材给出了 线索二叉树的中序递归线索化以及中序遍历,但是没给出非递归,现在网上大部分非递归算法代码各种条件判断写的比较离谱,所以干脆自己总结了一个清晰的.线索二叉树中序非递归线索化以及递归 ...

  5. 【代码随想录训练营】【Day14】第六章|二叉树|理论基础|递归遍历|迭代遍历|统一迭代

    理论基础 二叉树的定义形式有:节点指针和数组 在数组中,父节点的下标为i,那么其左孩子的下标即i*2+1,右孩子的下标即为i*2+2 二叉树的常见遍历形式有:前序遍历.后序遍历.中序遍历和层序遍历 前 ...

  6. 二叉树求深度的递归的详细分析

    >数据结构:typedef struct BINODE{TELEMETYPE data;struct BINODE *lchild,*rchild;}BiNode,*BiTtree;>递归 ...

  7. 二叉树的遍历 (递归和非递归实现)

    二叉树的遍历 (递归实现) 用C++实现二叉树的"先根遍历"存储. 用C++实现二叉树的"先根遍历"."中根遍历"."后根遍历&q ...

  8. 二叉树的遍历(递归,非递归,Morris)

    二叉树的遍历 目录 递归遍历 非递归遍历 Morris遍历 1. 递归遍历 递归版遍历只要当前节点不为null,就可以三次回到当前节点. public static void preOrderRecu ...

  9. linux 递归创建线程,[linux]二叉树的建立及其递归遍历(C语言实现)

    #二叉树的特点: 每一个节点最多有两棵子树,所以二叉树中不存在度大于2的节点,注意,是最多有两棵,没有也是可以的 左子树和右子树是有顺序的,次序不能颠倒,这点可以在哈夫曼编码中体现, 顺序不同编码方式 ...

  10. 数据结构(六)二叉树的遍历(递归非递归方法)

    数据结构(六)二叉树的遍历(递归非递归方法) 一.递归方法 1.先序遍历 void PreOrder(BiTree T) {visit(T);PreOrder(T->LChild)PreOrde ...

最新文章

  1. js你真的了解offsetWidth吗
  2. 数据结构与算法 / B- Tree 和 B+ Tree
  3. Codeforces Round #663 (Div. 2)
  4. javascript中数组、冒泡排序、函数及函数实参形参、arguments伪数组、异步函数等介绍
  5. c语言调用的viod函数不执行,void 函数 调用问题
  6. Struts2国际化——完整实例代码
  7. Leetcode 410.分割数组的最大值(最优解是二分法)
  8. Android模拟器adb命令介绍
  9. 19.Virtual Type
  10. Java直接遍历并读取zip压缩文件的内容以及错误处理
  11. WiFi HAL 启动
  12. CIC滤波器的设计与仿真
  13. win10 常用DOS命令
  14. 2021高考厦门科技中学成绩查询,2021年厦门重点高中名单及排名,厦门高中高考成绩排名榜...
  15. Python进行拉勾网数据爬取框架与思路
  16. 十分钟入门Matplotlib
  17. Mysql报错130_Mysql报错Forcing close of thread 139 user: 'root'
  18. oracle时间字段加几小时
  19. [递推] 51Nod1383 整数分解为2的幂
  20. android开发自定义相机镜像问题

热门文章

  1. 在TFS2013上删除项目
  2. 使用Win2D在UWP程序中2D绘图(二)
  3. ArcGIS Server Manager打不开(运行时错误)
  4. [转载]使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放...
  5. Android 编码规范:(二)遇到多个构造器参数时要考虑用构建器
  6. Logistic回归小结
  7. 3、electron打包生成exe文件
  8. cookie与session的区别,你真的明白吗?
  9. 使用solrj api操作solr
  10. 骨骼动画编辑器Spine的纹理打包器(texture packer)