LeetCode刷题day37

简介: LeetCode刷题day37

今日刷题重点–二叉树的路径以及左/右叶子之和.

257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例 1:


583a440bf8104497bab07118425f6e14.jpg

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]


示例 2:

输入:root = [1]
输出:["1"]


思路分析

这道题要求从根节点到叶子的路径所以需要先序遍历,这样方便父节点指向孩子节点.

因为找的是所有叶子节点的路径,所有递归中必有回溯思想.

示意图如下:


09d486cd1b1e417fbf437e344e404687.png

递归三要素:


参数和返回值:参数是要递归的树的根节点,另外需要一个vector<int> path记录递归到当前根节点的路径.还有一个vector<string> res 保存结果集.

由于遍历的是整棵树,所有不需要有返回值.

结束条件:当遇到叶子节点,就把path存入到res中.并结束本层递归

确定单层递归逻辑: 将左子树节点放入path,向左进行递归遍历,遍历完毕之后进行回溯. 之后将右子树节点放入path,向右进行递归遍历,遍历完毕后进行回溯.

运行结果


void traversal(TreeNode* node,vector<int> &path,vector<string> &res){//path:遍历到node时的路径,res:结果集也可以声明成全局变量,这样就可以不用参数传递了. 
  if(node->left==NULL&&node->right==NULL){//当该节点是叶子节点时. 
    string temp = "";
    int i;
    for(i = 0;i < path.size()-1;i++){
      temp+=to_string(path[i]);
      temp+="->";
    } 
    temp+=to_string(path[i]);
    res.push_back(temp);//加入到结果集中 
    return;//结束 
  }
  if(node->left){
    path.push_back(node->left->val);//把当前节点的值放入path中 
    traversal(node->left,path,res); 
    path.pop_back();//递归完成进行回溯(弹出node->left节点)..之后尝试其他路径 (比如node->right) 
  }
  if(node->right){
    path.push_back(node->right->val);
    traversal(node->right,path,res); 
    path.pop_back();//递归完成进行回溯..之后尝试其他路径 
  } 
}
//方法一:递归 
vector<string> binaryTreePaths(TreeNode* root) {
  vector<string> res;
  vector<int> path;
  if(root==NULL){
    return {};
  } 
  path.push_back(root->val);
  traversal(root,path,res);
  return res;
}

404. 左叶子之和

计算给定二叉树的所有左叶子之和。

示例:

    3
   / \
  9  20
    /  \
   15   7

在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

思路分析

注意判断的是左叶子,不是二叉树左侧节点,所以层次遍历这样的思路是不对的.

左叶子:如果左节点不为空,且左节点没有左右孩子,那么这个节点就是左叶子


cbc26bde737b486881b60233a51e11c2.png

比如上面这棵树的左叶子节点为0,因为它没有叶子位于左边.


方法1:递归法(菜鸡的做法)

既然是判断左叶子,那么该节点得符合当前节点是叶子节点,并且得满足父节点的左孩子是该节点.

递归三要素:


参数和返回值:参数就是当前节点以及其父节点. 由于存放结果的res是全局变量,所以不需要返回值.

结束条件:当节点是叶子节点时,判断父节点的左节点是否是该节点,然后进行处理.最后进行return,结束递归.

单层递归逻辑:更新父节点,继续向左递归遍历,向右递归遍历.

参考代码1

int res = 0; 
void traversal(TreeNode* cur,TreeNode* pre){
  if(!cur->left && !cur->right){//叶子节点 
    if(pre->left==cur){
      res+=cur->val;
    }
    return;
  }
  pre = cur;
  if(cur->left){
    traversal(cur->left,pre);
  }
  if(cur->right){
    traversal(cur->right,pre);
  }
} 
int sumOfLeftLeaves(TreeNode* root) {
  if(root==NULL) { //结束条件..
    return 0;
  }
  traversal(root,root); 
  return res;
}

方法2:递归法(大佬的做法)

递归三要素:


参数和返回值:参数为要遍历的树的根节点. 返回值左叶子之和,为int

递归结束条件:当节点为NULL时,返回0,表示左叶子节点为0

单层递归逻辑:先求左子树的左叶子节点之和left,再求右子树的左叶子节点之和,最后再求当前节点是否是左叶子节点如果是则保存其值, 最后的返回值是三部分之和.


参考代码2

//递归
int sumOfLeftLeaves(TreeNode* root) {//每一次都判断当前节点是不是左叶子节点的父节点,如果是进行操作.
  if(root==NULL) { //结束条件..
    return 0;
  }
  int leftSum = sumOfLeftLeaves(root->left);
  int rightSum = sumOfLeftLeaves(root->right);
  int midSum = 0;
  if(root->left&&!root->left->left&&!root->left->right) {
    midSum = root->left->val;
  }
  return leftSum+rightSum+midSum;
}

方法三:迭代法(层次遍历)

本题迭代法使用前中后序都是可以的,只要把左叶子节点统计出来,就可以了,以下是前序遍历的做法.

参考代码3

//迭代法
int sumOfLeftLeaves(TreeNode* root) {
  stack<TreeNode*> tab;
  if(root==NULL) {
    return 0;
  }
  tab.push(root);
  int res;
  while(!tab.empty()) {
    TreeNode* node = tab.top();
    tab.pop();
    if(node->left&&!node->left->left&&!node->left->right) {//当然这里也可以改成父节点pre,和当前节点的思路.
      res+=node->left->val;
    }
    if(node->right) {
      tab.push(node->right);
    }
    if(node->left) {
      tab.push(node->left);
    }
  }
  return res;
}
相关文章
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
59 6
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
52 4
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
121 2
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
36 1
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
4月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
67 7
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
54 5
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
29 4
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
29 4