(第27天)【leetcode题解】101、对称二叉树 100、相同的树 572、另一颗树的子树

2024-06-06 19:36

本文主要是介绍(第27天)【leetcode题解】101、对称二叉树 100、相同的树 572、另一颗树的子树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 101、对称二叉树
    • 题目描述
    • 思路
    • 代码
  • 100、相同的树
    • 题目描述
    • 思路
    • 代码
  • 572、另一颗树的子树
    • 题目描述
    • 思路
    • 代码
  • 总结

101、对称二叉树

题目描述

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

思路

题目分析

  • 检查二叉树是否对称,就是要检查根节点root的左右子树是否对称
  • 怎样检查root的左右子树是否对称呢?当root的左子树所有左子节点的值等于右子树所有右子节点的值 左子树所有右子节点的值等于右子树所有左子节点的值`时,这个二叉树时对称二叉树

递归法

  1. 返回值:bool
  2. 参数。left:root的左子树,right:root的右子树
  3. 终止条件:考虑左右子树的当前节点都为空的情况、考虑左右子树当前节点不相等的情况
  4. 递归逻辑:先向左右子树的外侧递归,对外侧节点进行比较;在向左右子树的内侧递归,对内侧节点进行比较。
  5. 递归函数做了什么?:根据传入的参数,采用类似于后序遍历的方式比较了左右子树的外侧节点值和内侧节点值。

使用队列实现迭代

  1. 若根节点非空,使用队列,往队列中按左右顺序加入左右子树的根节点。
  2. 进入循环,每次取出两个节点比较,若值不同返回false。(要对节点为NULL的情况做额外处理)
  3. 为了保证比较的节点符合判断二叉树是否对称的题目要求,在循环体的最后按照左子树的左节点、右子树的右节点、左子树的右节点、右子树的左节点的顺序把节点放入队列中。

使用栈实现迭代

  1. 核心思路:要判断二叉树是否对称,需要分别比较左右子树外侧节点和内侧节点。那么,把需要比较的元素按顺序放进容器中,每次取出一对进行比较就可以实现效果。

代码

递归法

class Solution {
public://递归函数//参数:left左子树、right右子树bool helper(TreeNode* left, TreeNode* right) {//终止条件//先考虑左右子树为空的情况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;//递归逻辑bool outside = helper(left -> left, right -> right);//左子树:左  右子树:右(比较外侧节点)bool inside = helper(left -> right, right -> left);//左子树:右  右子树:左(比较内侧节点)bool issame = outside && inside;//左子树:中 右子树:中return issame;//外侧节点和内侧节点都相等时返回true}bool isSymmetric(TreeNode* root) {if (root == NULL) return true;return helper(root -> left, root -> right);//传入左右子树}
};

使用队列实现迭代

class Solution {
public:bool isSymmetric(TreeNode* root) {if (root == NULL) return true;queue<TreeNode*> que;que.push(root -> left);que.push(root -> right);while (!que.empty()) {TreeNode* LeftNode = que.front(); que.pop();TreeNode* RightNode = que.front(); que.pop();if (!LeftNode && !RightNode) continue;//若比较的两个节点都为空,说明这时是对称的//若两节点有一个为空,或两节点的值不同,则不对称,直接返回flaseif (!LeftNode || !RightNode || (LeftNode -> val != RightNode -> val)) return false;//按顺序把节点加入队列中que.push(LeftNode -> left);//左子树:左que.push(RightNode -> right);//右子树:右que.push(LeftNode -> right);//左子树:右que.push(RightNode -> left);//右子树:左}return true;//若所有节点比较完没有发现不对称,则说明二叉树对称}
};

使用栈实现迭代

class Solution {
public:bool isSymmetric(TreeNode* root) {if (root == NULL) return true;//根节点为空,二叉树对称stack<TreeNode*> st;st.push(root -> left);st.push(root -> right);while (!st.empty()) {TreeNode* leftNode = st.top(); st.pop();TreeNode* rightNode = st.top(); st.pop();if (!leftNode && !rightNode) continue;if (!leftNode || !rightNode || (leftNode -> val != rightNode -> val)) return false;st.push(leftNode -> left);st.push(rightNode -> right);st.push(leftNode -> right);st.push(rightNode -> left);}return true;}
};

100、相同的树

题目描述

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

思路

递归法

  1. 返回值:bool
  2. 参数:p、q,代表子树和子树的节点
  3. 终止条件:p、q为空时对称;p、q有一个不为空时不对称;p、q都不为空但值不同时不对称。
  4. 递归逻辑:先比较p的所有左子节点和q的所有左子节点、再比较p的所有右子节点和q的所有右子节点。

迭代法

  1. 把需要比较的元素成对相邻的放入容器中,然后依次成对取出进行比较,若两个值不相同则表示两棵树不一样。

代码

递归法

class Solution {
public:bool isSameTree(TreeNode* p, TreeNode* q) {if (p == NULL && q == NULL) return true;//都为空,相同else if (p == NULL || q == NULL || (p -> val != q -> val)) return false;return isSameTree(p -> left, q -> left) && isSameTree(p -> right, q -> right);}
};

迭代法

class Solution {
public:bool isSameTree(TreeNode* p, TreeNode* q) {if (p == NULL && q == NULL) return true;queue<TreeNode*> que;que.push(p);que.push(q);while (!que.empty()) {TreeNode* qNode = que.front(); que.pop();TreeNode* pNode = que.front(); que.pop();if (qNode == NULL && pNode == NULL) continue;if (qNode == NULL || pNode == NULL || qNode -> val != pNode -> val) return false;que.push(qNode -> left);que.push(pNode -> left);que.push(qNode -> right);que.push(pNode -> right);}return true;}
};

572、另一颗树的子树

题目描述

  • 给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

  • 二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

思路

  • 题目分析

要检验一棵树是否是另一颗树的子树的三种可能:

  1. 两棵树相同:根节点都为空 两棵树相同
  2. 这棵树是另一颗树的左树的子树
  3. 这棵树是另一颗树的右树的子树
  1. 判断两棵树相同

根节点都为空,相同;根节点只有一个为空,不同。
比较当前的两个节点值
向左递归、向右递归

  1. 判断是否是大树左树的子树

主函数向左递归,每个递归里都判断一次当前子树是否和待检测树相同

  1. 判断是否是大树右树的子树

主函数向右递归,每个递归里都判断一次当前子树是否和待检测树相同

代码

class Solution {
public:bool isSameTree(TreeNode* root, TreeNode* subRoot) {if (root == NULL && subRoot == NULL) return true;//两棵树都为空时,相同else if (root == NULL || subRoot == NULL ) return false;//只有一个为空是,不同return (root->val == subRoot->val) //先比较两个节点的值&& isSameTree(root->left, subRoot->left) //向左递归,比较左子树&& isSameTree(root->right, subRoot->right);//向右递归,比较右子树}bool isSubtree(TreeNode* root, TreeNode* subRoot) {if (root == NULL && subRoot == NULL) return true;//两棵树都为空if (root == NULL && subRoot != NULL) return false;//大树为空,小树不为空return isSameTree(root, subRoot) //两树相同|| isSubtree(root->left, subRoot)//判断subRoot是否是左树的子树|| isSubtree(root->right, subRoot);//判断subRoot是否是右数的子树}
};

总结

  • 在对节点进行比较时,要处理好节点为空的情况

因为在这一类型题中,比较节点值是通过node -> val进行的,若没有处理节点为空的情况,则在处理数据时会报错。
因此,对于节点为空的情况,需要单独处理。

这篇关于(第27天)【leetcode题解】101、对称二叉树 100、相同的树 572、另一颗树的子树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1037037

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样