LeetCodeHot100|对称二叉树、二叉树的直径、二叉树的层序遍历

对称二叉树

给你一个二叉树的根节点,判断它是否对称

输入: root = [1,2,2,3,4,4,3]

输出: true

思路分析

使用递归来解题,因为是求对称,所以判断的时候需要满足两个点,第一个点就是任意根节点的左子树等于右子树,具有相同的值。第二个点就是镜像对称。

具体可以使用递归函数,通过同步移动两个指针的方法来遍历这颗树,p指针和q指针一开始都指向这颗树的根,随后p左移的时候p右移,p右移的时候q左移,每次检查当前p和q节点的值是否相等,如果相等再判断左右子树是否对称。

代码解读

cpp 复制代码
/**

 * Definition for a binary tree node.

 * struct TreeNode {

 *     int val;

 *     TreeNode *left;

 *     TreeNode *right;

 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}

 *     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 isSymmetric(TreeNode* root) {

        // 1.检查是否轴对称

        // 既然要检测树,那么如何去找左右节点呢?-> 使用指针移动

        return root == nullptr || recur(root -> left, root -> right);

    }

/**

终止条件 L 和 R 同时越过叶节点,此树从顶至底的节点都对称,

*/

private:

    bool recur(TreeNode* L, TreeNode* R) {  

        if (L == nullptr && R ==nullptr) return true;

        if(L == nullptr || R == nullptr || L -> val != R ->val) return false;

        return recur(L -> left, R -> right) && recur(L->right, R->left);

  

    }

};

二叉树的直径

给你一颗二叉树的根节点,返回该树的直径

二叉树的直径是指树中任意两个节点之间最长路径的长度。这条路径可能经过也可能不经过根节点root,两节点之间路径的长度由它们之间的边数表示。

解题思路

首先需要知道求直径相当于求什么。一条路径的长度为该路径经过的节点数减一,所以求直径等效于求路径经过节点数的最大值减一。比如4到1就是三个节点,减去一个节点就是2.

而任意一个路径都可以被看作是某一个节点为起点,从其左儿子和右儿子向下便利的路径拼接得到。

假设我们知道对于该节点的左儿子向下便利经过最多的节点数L和其右儿子向下便利经过节点R,那么以该节点为起点的路径经过节点数最大值为 L+R+1.

cpp 复制代码
class Solution { 
	int ans; // 全局变量: 记录二叉树中 最长路径的节点总数
	
	// 定义一个递归函数: 计算以rt为根的子树的最大深度
	int depth(TreeNode* rt) { 
		// 递归终止条件: 空节点深度为 0
		if(rt == NULL) { 
			return 0;
		}
		
		// 后序便利: 先计算左子树的深度L
		int L = depth(rt -> left);
		// 再计算右子树深度 R
		int R = depth(rt -> right);
		
		// 核心: 当前节点的路径长度 = 左深度 + 右深度  +1 
		ans = max(ans, L + R + 1); // 这里是更新当前的全局最大值
		
		return max(L,R)  +1;
		
	}
public:
	// 主函数:求二叉树的直径
	int diameterOfBinaryTree(TreeNode* root) { 
		// 初始化:最少一个节点
		ans = 1;
		// 递归便利整颗树, 计算所以节点的路径
		depth(root);
		// 直接 = 最长路径节点数 - 1
		return ans - 1;
	}
}

102.二叉树的层序遍历

给你二叉树的根节点root,返回其节点值的层序遍历。

**输入:root = [3,9,20,null,null,15,7]

输出:[[[3],[9,20],[15,7]]

思路分析

首先题目要求是按层打印,又被称为二叉树的广度优先搜索BFS. 而BFS是借助队列的先入先出的特性来实现的。

cpp 复制代码
/**

 * Definition for a binary tree node.

 * struct TreeNode {

 *     int val;

 *     TreeNode *left;

 *     TreeNode *right;

 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}

 *     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:
	// 二叉树层序便利,返回二维数组,每一层对应一个一维数组
    vector<vector<int>> levelOrder(TreeNode* root) {
		// 队列,用于BFS, 存储节点指针, 利用先进先出实现层序
		queue<TreeNode*> que;
		// 用于存放最终结果;每一层一组节点值
		vector<vector<int>> res;
		// 如果根节点非空,先将根节点入队
        if(root != nullptr) que.push(root);
		// 队列不为空,说明还有节点未遍历
        while(!que.empty()) {
			// 临时数组,存放当前这一层的所有节点值
            vector<int> tmp;
			// 关键: 只循环当前层的节点个数
            for(int i = que.size();i > 0; --i) {
				// 取出队首节点
                root = que.front(); // 取出首队列和弹出首队列
				// 谈出队首节点
                que.pop();
				// 将节点值加入当前层数组
                tmp.push_back(root-> val);
				// 左孩子不为空则入队,作为下一层节点
                if( root -> left != nullptr) que.push(root -> left);
				
                if (root -> right != nullptr) que.push(root -> right);

            }
			// 当前层便利完毕,这一层结果加入最终结果
            res.push_back(tmp);

        }

        return res;

    }

};
相关推荐
nianniannnn2 小时前
力扣 3.无重复字符的最长子串
c++·算法·leetcode
羊小猪~~2 小时前
【QT】-- 模型与视图简介
开发语言·数据库·c++·后端·qt·前端框架·个人开发
小碗羊肉2 小时前
【数据结构】平衡二叉树的旋转机制
数据结构·二叉树
always_TT2 小时前
指针与结构体:链表节点设计
数据结构·链表
水饺编程2 小时前
第4章,[标签 Win32] :SysMets3 程序讲解02,iVertPos
c语言·c++·windows·visual studio
Yungoal2 小时前
数据结构综合0-排序
数据结构
西西弟2 小时前
最短路径之Floyd算法(数据结构)
数据结构·算法
SilentSlot2 小时前
【数据结构】红黑树定义及基本操作
数据结构
Hello-FPGA3 小时前
视觉软件工程师(机器视觉 / 科学成像方向)
c++