12.30 二叉树中等题

2023-12-30 21:20
文章标签 二叉树 中等 12.30

本文主要是介绍12.30 二叉树中等题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

思路1:

要让depth尽可能大,则如果从底向上去遍历节点,那第一个满足是p、q公共祖先的节点即是答案

细节:后序遍历是从底向上遍历二叉树

采用递归方法进行后序遍历:

1.递归结构:

        TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点

终止递归的条件:root==nullptr

判断是否为P、Q的祖先节点:判断left和right是否为null并重新写一个isChild进行递归判断,

class Solution {
public:bool isChild(TreeNode* root,TreeNode* target){if(root==target) return true;else if(root==NULL) return false;return isChild(root->left,target) || isChild(root->right,target);}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == NULL) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点if(left!=NULL) return left;else if(right!=NULL) return right;else if(isChild(root,p)&&isChild(root,q)) return root;return NULL;}
};

这段代码的时间复杂度是O(N^2),其中N是二叉树中节点的数量。原因是在lowestCommonAncestor函数中,对于每个节点都会调用isChild函数,而isChild函数的时间复杂度是O(N),因为它需要递归遍历整个树来查找目标节点。

下面这个方法的复杂度为o(N)。

思路2:

代码随想录 (programmercarl.com)

要让depth尽可能大,则如果从底向上去遍历节点,那第一个满足是p、q公共祖先的节点即是答案

细节:后序遍历是从底向上遍历二叉树

采用递归方法进行后序遍历:

递归结构:

        TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点

终止递归的条件:root==nullptr或==p或==q

        if (root == q || root == p || root == NULL) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点

判断该节点是否为P、q公共祖先节点可以利用返回的left、right值:

left、right的取值有四种情况:

1.left right 都为nullptr

则该root不是p q的祖先节点

2.left 为nullptr而right不为nullptr

则left不会是 p q的祖先节点,right可能是

3.right 为nullptr而left不为nullptr

则right不会是 p q的祖先节点,left可能是

4.left right 都不为nullptr

则root一定为 p 、q的公共祖先节点。该root返回到上一层递归中时,与该root对应的兄弟节点一定会是nullptr,则继续返回该root,直到第一层。

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == q || root == p || root == NULL) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);//再判断该节点是否为P、q公共祖先节点if (left != NULL && right != NULL) return root;if (left == NULL) return right;return left;}
};

在最坏情况下,需要遍历整个二叉树,因此时间复杂度是O(N),其中N是二叉树中节点的数量。

这篇关于12.30 二叉树中等题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

在二叉树中找到两个节点的最近公共祖先(基于Java)

如题  题解 public int lowestCommonAncestor(TreeNode root, int o1, int o2) {//记录遍历到的每个节点的父节点。Map<Integer, Integer> parent = new HashMap<>();Queue<TreeNode> queue = new LinkedList<>();parent.put(roo

数据结构--二叉树(C语言实现,超详细!!!)

文章目录 二叉树的概念代码实现二叉树的定义创建一棵树并初始化组装二叉树前序遍历中序遍历后序遍历计算树的结点个数求二叉树第K层的结点个数求二叉树高度查找X所在的结点查找指定节点在不在完整代码 二叉树的概念 二叉树(Binary Tree)是数据结构中一种非常重要的树形结构,它的特点是每个节点最多有两个子节点,通常称为左子节点和右子节点。这种结构使得二叉树在数据存储和查找等方面具

【中等】保研/考研408机试-二分查找(模板题)

二分查找就是在一个有序数组中查找某个值,以首端尾端的中点mid查找对比,mid与要查找的数进行对比,看落在哪个区间,在那个区间重新得到首端和尾端,进而得到新的mid值。 一、模板题 二分查找-I_牛客题霸_牛客网 class Solution {public:int search(vector<int>& nums, int target) {int left=0,right=nums.s

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息publ

222.完全二叉树的节点个数

(写给未来遗忘的自己) 题目: 代码: class Solution {public:int countNodes(TreeNode* root) {queue<TreeNode*>node_que;if(root==nullptr) return 0;node_que.push(root);int result;while(!node_que.empty()){int layer_s

代码随想录 -- 二叉树 -- 平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode) 思路:仍然是递归调用 1. 定义一个递归函数 count 用来计算二叉树的层数 2. isBalanced 函数:如果传入根节点为空返回真;如果根节点 | 左子树的层数 - 右子树的层数 | 大于1,返回假;最后返回根节点左子树、右子树是否是平衡二叉树。 class Solution(object):def count(self,root

【数据结构】你真的学会了二叉树了吗,来做一做二叉树的算法题及选择题

文章目录 1. 二叉树算法题1.1 单值二叉树1.2 相同的树1.3 另一棵树的子树1.4 二叉树的遍历1.5 二叉树的构建及遍历 2. 二叉树选择题3. 结语 1. 二叉树算法题 1.1 单值二叉树 https://leetcode.cn/problems/univalued-binary-tree/description/ 1.2 相同的树 https://leet

Java中等题-整数替换(力扣)

给定一个正整数 n ,你可以做如下操作: 如果 n 是偶数,则用 n / 2替换 n 。如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。 返回 n 变为 1 所需的 最小替换次数 。 示例 1: 输入:n = 8输出:3解释:8 -> 4 -> 2 -> 1 示例 2: 输入:n = 7输出:4解释:7 -> 8 -> 4 -> 2 -> 1或 7 ->