码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 代码随想录算法训练营第23期day14|二叉树层序遍历、226.翻转二叉树、101. 对称二叉树


    目录

    一、二叉树层序遍历

    非递归法

    递归法

    相关题目(10题)

     二、(leetcode 226)翻转二叉树

    递归法

    层序遍历

    深度优先遍历

    1)非统一写法——前序遍历

    2) 统一写法——前序遍历

    三、(leetcode 101)对称二叉树

    递归法

    迭代法

    1)使用队列

    2)使用栈


    一、二叉树层序遍历

    借用队列实现,因为队列先进先出,符合层序遍历逻辑

    非递归法

    1. class Solution {
    2. public:
    3. vectorint>> levelOrder(TreeNode* root) {
    4. queue que;
    5. if (root != NULL) que.push(root);
    6. vectorint>> result;
    7. while (!que.empty()) {
    8. int size = que.size();
    9. vector<int> vec;
    10. // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
    11. for (int i = 0; i < size; i++) {
    12. TreeNode* node = que.front();
    13. que.pop();
    14. vec.push_back(node->val);
    15. if (node->left) que.push(node->left);
    16. if (node->right) que.push(node->right);
    17. }
    18. result.push_back(vec);
    19. }
    20. return result;
    21. }
    22. };

    递归法

    1. class Solution {
    2. public:
    3. void order(TreeNode* cur, vectorint>>& result, int depth)
    4. {
    5. if (cur == nullptr) return;
    6. if (result.size() == depth) result.push_back(vector<int>());
    7. result[depth].push_back(cur->val);
    8. order(cur->left, result, depth + 1);
    9. order(cur->right, result, depth + 1);
    10. }
    11. vectorint>> levelOrder(TreeNode* root) {
    12. vectorint>> result;
    13. int depth = 0;
    14. order(root, result, depth);
    15. return result;
    16. }
    17. };

    相关题目(10题)

    • 102.二叉树的层序遍历(opens new window)
    • 107.二叉树的层次遍历II(opens new window)
    • 199.二叉树的右视图(opens new window)
    • 637.二叉树的层平均值(opens new window)
    • 429.N叉树的层序遍历(opens new window)
    • 515.在每个树行中找最大值(opens new window)
    • 116.填充每个节点的下一个右侧节点指针(opens new window)
    • 117.填充每个节点的下一个右侧节点指针II(opens new window)
    • 104.二叉树的最大深度(opens new window)
    • 111.二叉树的最小深度

     二、(leetcode 226)翻转二叉树

    力扣题目链接

    状态:递归法、层序遍历AC,深度优先遍历还需回顾(原始代码就没有看的很清楚)

    递归法

    前序、后序遍历都可以,中序不行

    1. class Solution {
    2. public:
    3. TreeNode* invertTree(TreeNode* root) {//确定递归函数的参数和返回值
    4. if (root == NULL) return root; //确定终止条件
    5. //确定单层递归的逻辑
    6. swap(root->left, root->right); // 中
    7. invertTree(root->left); // 左
    8. invertTree(root->right); // 右
    9. return root;
    10. }
    11. };

    中序遍历不行的原因:

    传统的递归不行,注意最后还是遍历左孩子,因为中间节点翻转时已经将左右调转了

    1. class Solution {
    2. public:
    3. TreeNode* invertTree(TreeNode* root) {
    4. if (root == NULL) return root;
    5. invertTree(root->left); // 左
    6. swap(root->left, root->right); // 中
    7. invertTree(root->left); // 注意 这里依然要遍历左孩子,因为中间节点已经翻转了
    8. return root;
    9. }
    10. };

    层序遍历

    1. class Solution {
    2. public:
    3. TreeNode* invertTree(TreeNode* root) {
    4. queue que;
    5. if (root != NULL) que.push(root);
    6. while (!que.empty()) {
    7. int size = que.size();
    8. for (int i = 0; i < size; i++) {
    9. TreeNode* node = que.front();
    10. que.pop();
    11. swap(node->left, node->right); // 节点处理
    12. if (node->left) que.push(node->left);
    13. if (node->right) que.push(node->right);
    14. }
    15. }
    16. return root;
    17. }
    18. };

    深度优先遍历

    1)非统一写法——前序遍历

    1. class Solution {
    2. public:
    3. TreeNode* invertTree(TreeNode* root) {
    4. if (root == NULL) return root;
    5. stack st;
    6. st.push(root);
    7. while(!st.empty()) {
    8. TreeNode* node = st.top(); // 中
    9. st.pop();
    10. swap(node->left, node->right);
    11. if(node->right) st.push(node->right); // 右
    12. if(node->left) st.push(node->left); // 左
    13. }
    14. return root;
    15. }
    16. };

    2) 统一写法——前序遍历

    1. class Solution {
    2. public:
    3. TreeNode* invertTree(TreeNode* root) {
    4. stack st;
    5. if (root != NULL) st.push(root);
    6. while (!st.empty()) {
    7. TreeNode* node = st.top();
    8. if (node != NULL) {
    9. st.pop();
    10. if (node->right) st.push(node->right); // 右
    11. if (node->left) st.push(node->left); // 左
    12. st.push(node); // 中
    13. st.push(NULL);
    14. } else {
    15. st.pop();
    16. node = st.top();
    17. st.pop();
    18. swap(node->left, node->right); // 节点处理逻辑
    19. }
    20. }
    21. return root;
    22. }
    23. };

    三、(leetcode 101)对称二叉树

    力扣题目链接

    状态:递归法顺利AC,迭代法中使用栈的思路清楚并AC,使用队列的部分有点乱

    递归法

    1. class Solution {
    2. public:
    3. bool compare(TreeNode* left, TreeNode* right) {
    4. if (left == NULL && right != NULL) return false;
    5. else if (left != NULL && right == NULL) return false;
    6. else if (left == NULL && right == NULL) return true;
    7. else if (left->val != right->val) return false;
    8. else return compare(left->left, right->right) && compare(left->right, right->left);
    9. }
    10. bool isSymmetric(TreeNode* root) {
    11. if (root == NULL) return true;
    12. return compare(root->left, root->right);
    13. }
    14. };

    迭代法

    1)使用队列

    1. class Solution {
    2. public:
    3. bool isSymmetric(TreeNode* root) {
    4. if (root == NULL) return true;
    5. queue que;
    6. que.push(root->left); // 将左子树头结点加入队列
    7. que.push(root->right); // 将右子树头结点加入队列
    8. while (!que.empty()) { // 接下来就要判断这两个树是否相互翻转
    9. TreeNode* leftNode = que.front(); que.pop();
    10. TreeNode* rightNode = que.front(); que.pop();
    11. if (!leftNode && !rightNode) { // 左节点为空、右节点为空,此时说明是对称的
    12. continue;
    13. }
    14. // 左右一个节点不为空,或者都不为空但数值不相同,返回false
    15. if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
    16. return false;
    17. }
    18. que.push(leftNode->left); // 加入左节点左孩子
    19. que.push(rightNode->right); // 加入右节点右孩子
    20. que.push(leftNode->right); // 加入左节点右孩子
    21. que.push(rightNode->left); // 加入右节点左孩子
    22. }
    23. return true;
    24. }
    25. };

    2)使用栈

    把左右两个子树要比较的元素顺序放进一个容器,然后成对成对的取出来进行比较

    1. class Solution {
    2. public:
    3. bool isSymmetric(TreeNode* root) {
    4. if (root == NULL) return true;
    5. stack st; // 这里改成了栈
    6. st.push(root->left);
    7. st.push(root->right);
    8. while (!st.empty()) {
    9. TreeNode* leftNode = st.top(); st.pop();
    10. TreeNode* rightNode = st.top(); st.pop();
    11. if (!leftNode && !rightNode) {
    12. continue;
    13. }
    14. if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
    15. return false;
    16. }
    17. st.push(leftNode->left);
    18. st.push(rightNode->right);
    19. st.push(leftNode->right);
    20. st.push(rightNode->left);
    21. }
    22. return true;
    23. }
    24. };

     

  • 相关阅读:
    spring框架历史漏洞复现
    Docker搭建elasticsearch-7.8.0单机版本
    系统架构师备考倒计时18天(每日知识点)
    太强了吧,架构师联手总结17w字的计算机基础知识与操作系统PDF
    【设计模式】Java设计模式 - 状态模式
    saltstack运维工具包salt-api代码记录
    14天学习训练营导师课程-Pygame学习笔记-Part2(第九艺术的召唤)
    论文阅读KVQ: Kwai Video Quality Assessment for Short-form Videos
    Flink 1.13 源码解析——JobManager启动流程概览
    竞赛选题 基于机器视觉的银行卡识别系统 - opencv python
  • 原文地址:https://blog.csdn.net/weixin_42179093/article/details/133615547
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号