算法训练day15Leetcode102二叉树层序遍历226翻转二叉树101对称二叉树

这篇具有很好参考价值的文章主要介绍了算法训练day15Leetcode102二叉树层序遍历226翻转二叉树101对称二叉树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天学习的文章和视频链接

https://www.bilibili.com/video/BV1ue4y1Y7Mf/?vd_source=8272bd48fee17396a4a1746c256ab0ae

102 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:


输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:

输入:root = [1]
输出:[[1]]
示例 3:

输入:root = []
输出:[]
 
 提示:

树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000

题目分析

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。

acm模式代码

#include <iostream>
#include <vector>
#include <queue>
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x):val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right):val(x), left(left), right(right) {}
};
class Solution {
public:
    std::vector<std::vector<int>> levelOrder(TreeNode* root) {
        std::queue<TreeNode*> que;
        std::vector<std::vector<int>> result;
        if (root != nullptr) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            std::vector<int> vec;
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                vec.push_back(node->val);
                que.pop();
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};

int main() {
    // 创建一个简单的二叉树
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);

    Solution sol;
    std::vector<std::vector<int>> level_order = sol.levelOrder(root);

    // 打印层序遍历结果
    std::cout << "层序遍历:" << std::endl;
    for (const auto& level : level_order) {
        for (int val : level) {
            std::cout << val << " ";
        }
        std::cout << std::endl;
    }
}

226 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:


输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
示例 2:


输入:root = [2,1,3]
输出:[2,3,1]
示例 3:

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

提示:

树中节点数目范围在 [0, 100] 内
-100 <= Node.val <= 100

题目分析

确定递归函数的参数和返回值
参数就是要传入节点的指针,不需要其他参数了,通常此时定下来主要参数,如果在写递归的逻辑中发现还需要其他参数的时候,随时补充。

返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*。

TreeNode* invertTree(TreeNode* root)

确定终止条件
当前节点为空的时候,就返回

if (root == NULL) return root;

确定单层递归的逻辑
因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。

swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);

acm模式代码

#include <iostream>
#include <algorithm>

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x):val(x), left(nullptr),right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right):val(x), left(left), right(right) {}
};


class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == nullptr) {
            if (root == nullptr) {return root;}
        }
        std::swap(root->left,root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};

void printTree(TreeNode* root) {
    if (root != nullptr) {
        std::cout << root->val << " ";
        printTree(root->left);
        printTree(root->right);
    }
}

int main() {
    // 创建一个简单的二叉树
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);

    std::cout << "Original tree: ";
    printTree(root);
    std::cout << std::endl;

    Solution sol;
    root = sol.invertTree(root);

    std::cout << "Inverted tree: ";
    printTree(root);
    std::cout << std::endl;

    // 清理分配的内存
    delete root->left->left;
    delete root->left->right;
    delete root->left;
    delete root->right;
    delete root;

    return 0;
}

101 对称二叉树

题目分析

给你一个二叉树的根节点 root , 检查它是否轴对称。

 

示例 1:


输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:


输入:root = [1,2,2,null,3,null,3]
输出:false
 

提示:

树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100
 

进阶:你可以运用递归和迭代两种方法解决这个问题吗?

题目分析

首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!

对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。

本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。

正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

但都可以理解算是后序遍历,尽管已经不是严格上在一个树上进行遍历的后序遍历了。

其实后序也可以理解为是一种回溯,当然这是题外话,讲回溯的时候会重点讲的

递归法

递归三部曲

确定递归函数的参数和返回值
因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。

返回值自然是bool类型。

bool compare(TreeNode* left, TreeNode* right)

确定终止条件
要比较两个节点数值相不相同,首先要把两个节点为空的情况弄清楚!否则后面比较数值的时候就会操作空指针了。

节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点)

左节点为空,右节点不为空,不对称,return false
左不为空,右为空,不对称 return false
左右都为空,对称,返回true
此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:

左右都不为空,比较节点数值,不相同就return false
此时左右节点不为空,且数值也不相同的情况我们也处理了。

if (left == NULL && right != NULL) return false;
else if (left != NULL && right == NULL) return false;
else if (left == NULL && right == NULL) return true;
else if (left->val != right->val) return false; // 注意这里我没有使用else

确定单层递归的逻辑
此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。

比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。
如果左右都对称就返回true ,有一侧不对称就返回false 。
代码如下:文章来源地址https://www.toymoban.com/news/detail-800084.html

bool outside = compare(left->left, right->right);   // 左子树:左、 右子树:右
bool inside = compare(left->right, right->left);    // 左子树:右、 右子树:左
bool isSame = outside && inside;                    // 左子树:中、 右子树:中(逻辑处理)
return isSame;

acm 完整代码

#include <iostream>

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x): val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right): val(x), left(left), right(right) {}
};

class Solution {
public:
    bool compare(TreeNode* left, TreeNode* right) {
        if (left == nullptr && right != nullptr) return false;
        else if (left != nullptr && right == nullptr) return false;
        else if (left == nullptr && right == nullptr) return true;
        else if (left->val != right->val) return false;

        bool outside = compare(left->left, right->right);
        bool inside = compare(left->right, right->left);
        bool isSame = outside && inside;
        return isSame;
    }
    bool isSymmetric(TreeNode* root) {
        if (root == nullptr) return true;
        return compare(root->left, root->right);
    }
};

int main() {
    // 创建一个简单的对称二叉树
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(2);
    root->left->left = new TreeNode(3);
    root->left->right = new TreeNode(4);
    root->right->left = new TreeNode(4);
    root->right->right = new TreeNode(3);

    Solution sol;
    bool result = sol.isSymmetric(root);

    std::cout << "Is the tree symmetric? " << (result ? "Yes" : "No") << std::endl;

    // 清理分配的内存
    delete root->left->left;
    delete root->left->right;
    delete root->left;
    delete root->right->left;
    delete root->right->right;
    delete root->right;
    delete root;

    return 0;
}

到了这里,关于算法训练day15Leetcode102二叉树层序遍历226翻转二叉树101对称二叉树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【LeetCode】102.二叉树的层序遍历

    给你二叉树的根节点  root  ,返回其节点值的  层序遍历  。 (即逐层地,从左到右访问所有节点)。 示例 1: 示例 2: 示例 3: 提示: 树中节点数目在范围  [0, 2000]  内 -1000 = Node.val = 1000 之前做的题里深度优先遍历(DFS)用得比较多,主要是回溯算法,这道题的层序遍

    2024年02月15日
    浏览(41)
  • 【LeetCode热题100】--102.二叉树的层序遍历

    广度优先搜索: 我们可以想到最朴素的方法是用一个二元组 (node, level) 来表示状态,它表示某个节点和它所在的层数,每个新进队列的节点的 level 值都是父亲节点的 level 值加一。最后根据每个点的 level 对点进行分类,分类的时候我们可以利用哈希表,维护一个以 level 为键

    2024年02月07日
    浏览(39)
  • 每日一题:LeetCode-102.二叉树的层序遍历

    前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈    🔎🔎如果说代码有灵魂,那么它的灵魂一定是👉👉 算法 👈👈,因此,想要写出💚优美的程序💚,核心算法是必不可少的,少年,你渴望力量吗😆😆,想掌握程序的灵魂吗❓❗️那么就必须踏上这样一条漫长

    2024年02月05日
    浏览(40)
  • 二叉树层序遍历

    目录 一、什么是层序遍历 二、层序遍历的实现 三、判断一棵树是否为完全二叉树 总结: 学习二叉树结构,最简单的就是遍历。 所谓二叉树遍历就是按照某种规则对二叉树中的节点进行相应操作,每个节点值操作一次。 遍历是二叉树的重要运算之一,也是二叉树进行其它运

    2024年02月13日
    浏览(37)
  • day15 层序遍历 翻转二叉树 对称二叉树

    题目链接:102 二叉树的层序遍历 题意 根据二叉树的根节点root,返回其节点值的层序遍历 借助队列实现,因为队列是先进先出的逻辑,符合层序遍历一层一层遍历的思想 代码 题目链接:226 翻转二叉树 题意 根据二叉树的根节点root,翻转二叉树,将节点是左右孩子进行翻转

    2024年01月22日
    浏览(47)
  • 数据结构——二叉树层序遍历

    来喽来喽~ 二叉树的层序遍历来喽~ 层序遍历那是相当有趣滴! 我的朋友,请不要迷惘,你要记住,你终有鲲鹏一日! 加油吧!从现在开始~ 层序遍历 :除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所

    2024年02月07日
    浏览(46)
  • day15 | 层序遍历、 226.翻转二叉树、 101. 对称二叉树

    目录: 题目链接: 层序遍历 给你二叉树的根节点  root  ,返回其节点值的  层序遍历  。 (即逐层地,从左到右访问所有节点)。 随想录:借助一个队列实现。 102. 二叉树的层序遍历 107.二叉树的层次遍历 II 最后只需要将result的顺序改一下就行,但是注意,reverse是直接

    2024年02月08日
    浏览(74)
  • 算法训练day17leetcode110平衡二叉树257二叉树的所有路径404左叶子之和

    https://www.bilibili.com/video/BV1GY4y1K7z8/?vd_source=8272bd48fee17396a4a1746c256ab0ae https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html#%E6%80%9D%E8%B7%AF 采用后序递归遍历,比较左右子树的高度,相差小于等于1 前序,中左右,从根节点到叶子节点,会一直向下遍历下去,不会返回信

    2024年01月19日
    浏览(43)
  • ★102. 二叉树的层序遍历

    很巧妙的,又学习了一种层次遍历的方法, 就是说根据当前的队列的长度去遍历,遍历的当前队列的长度就是该层次的节点个数。

    2024年02月05日
    浏览(43)
  • 算法训练day16Leetcode104二叉树最大深度111二叉树最小深度222完全二叉树的节点个数

    https://www.bilibili.com/video/BV1Gd4y1V75u/?vd_source=8272bd48fee17396a4a1746c256ab0ae 用递归,但是什么顺序没想清楚 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始) 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边

    2024年01月16日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包