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

本文介绍了一种寻找二叉树中两个节点的最低公共祖先的有效算法。通过递归遍历二叉树,当遇到目标节点之一时返回该节点,最终在某个节点处左右子树均找到目标节点之一,则该节点即为最低公共祖先。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null){
            return null;
        }
        // 如果根和其中之一相同,那么根就是最低的公共祖先,另一者必然在根的左/右子树中
        if(root==p||root==q){
            return root;
        }
        // 如果返回的不为null,那么就是第一个等于p/q其中之一的节点
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);
        // p,q都存在于树中,所以不会全空
        if(left!=null&&right!=null){
            return root;
        }else if(left!=null){
            // right == null
            return left;
        }else{
            return right;
        }
    }
}

 

【太阳能学报EI复现】基于粒子群优化算法的风-水电联合优化运行分析(Matlab代码实现)内容概要:本文档是一份关于“基于粒子群优化算法的风-水电联合优化运行分析”的研究资料,旨在通过Matlab代码实现对该优化模型的复现。文档重点介绍了如何利用粒子群优化(PSO)算法解决风能与水能联合调度中的复杂优化问题,包括系统建模、目标函数构建、约束条件处理及算法实现过程。研究兼顾可再生能源的不确定性与电力系统运行的经济性,通过仿真验证了该方法在提升能源利用率和系统稳定性方面的有效性。此外,文档还附带多个相关领域的Matlab代码案例,涵盖微电网调度、储能配置、负荷预测等,突出其在电力系统优化中的实际应用价值。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源优化调度的工程技术人员;尤其适合希望复现EI期刊论文或开展智能优化算法在能源领域应用研究的用户。; 使用场景及目标:①学习并复现基于粒子群算法的风-水电联合运行优化模型;②掌握Matlab在电力系统优化中的建模与仿真方法;③拓展至微电网、储能调度、多能源协同优化等相关课题的研究与开发。; 阅读建议:建议结合文档中提供的Matlab代码进行逐模块调试与分析,重点关注目标函数设计、粒子群算法参数设置及约束处理机制。同时可参考文中列举的其他优化案例,举一反三,提升对智能算法在能源系统中综合应用的理解与实践能力。
<think>嗯,用户让我介绍一下ThreadLocal,包括它存的是什么,数据结构是怎样的,还要比较rehash和链表/红黑树的优缺点。另外还有LeetCode 236题,二叉树最近公共祖先。我需要先理清楚每个部分的知识点,然后组织语言回答。 首先,ThreadLocal。ThreadLocal是Java中的线程局部变量,每个线程都有独立的副本,用来解决多线程的并发问题。它存的是线程本地的变量,每个线程通过ThreadLocalMap来存储数据,这个Map的key是ThreadLocal实例本身,value是设置的值。数据结构方面,ThreadLocalMap使用了一个Entry数组,Entry继承自WeakReference,key是弱引用,value是强引用。这样设计可能导致内存泄漏,需要调用remove方法清理。 关于rehash,当哈希表负载因子达到阈值时,会进行扩容,重新计算所有元素的位置。ThreadLocalMap的rehash是线性的探测,遇到冲突就找下一个空槽,而像HashMap在Java8之后用链表转红黑树。比较的话,线性探测的优点是内存连续,缓存友好,但扩容可能更频繁,链表/红黑树处理冲突更高效,尤其数据量大时红黑树能保持O(logn)查询,但内存不连续,节点需要额外空间。可能用户想了解不同冲突解决方式的优劣,以及为什么ThreadLocal采用线性探测而不是其他结构。 然后是LeetCode 236题,二叉树最近公共祖先。需要找到两个节点的最低公共祖先。通常解法是后序遍历,递归查找左右子树是否包含p或q。如果左右都有,当前节点就是LCA。如果一边有,另一边没有,则返回有的那边。需要处理当前节点等于p或q的情况,直接返回当前节点。可能还要考虑边界情况,比如其中一个节点是另一个的祖先。 现在需要把这些内容有条理地整理出来,分点回答,确保准确且易懂。可能用户是在准备面试,所以需要详细但不过于冗长的解释。注意ThreadLocal的内存泄漏问题和解决方案,以及在数据结构选择上的权衡。对于算法题,可能需要给出思路、关键点以及可能的代码实现。 检查是否有遗漏点,比如ThreadLocalMap的哈希函数,或者线性探测的具体步骤。在比较rehash方法时,要强调不同场景下的适用性。对于算法题,确认是否最优解,是否有其他方法比如存储父节点然后比较路径等。确保回答覆盖所有问题点,并且逻辑清晰。</think>### 一、ThreadLocal详解 --- #### 1. **ThreadLocal存的是什么?** ThreadLocal 存储的是**线程本地变量**,每个线程通过 ThreadLocal 可以持有独立的变量副本,避免多线程竞争。数据实际存储在 `ThreadLocalMap` 中(每个线程的 `Thread` 对象内部有一个 `threadLocals` 字段)。 #### 2. **数据结构:ThreadLocalMap** - **实现方式**:`ThreadLocalMap` 是 ThreadLocal 的静态内部类,使用一个 `Entry` 数组存储键值对。 - **Entry 设计**: ```java static class Entry extends WeakReference<ThreadLocal<?>> { Object value; Entry(ThreadLocal<?> k, Object v) { super(k); // Key 是弱引用(避免内存泄漏) value = v; // Value 是强引用 } } ``` - **哈希冲突解决**:使用**开放地址法(线性探测)**,而非链表或红布树。冲突时依次向后查找空槽。 #### 3. **Rehash 机制与链表/红布树的对比** | **特性** | **ThreadLocalMap(线性探测)** | **HashMap(链表/红布树)** | |-------------------|--------------------------------------|------------------------------------| | **内存占用** | 连续内存,缓存友好 | 链表/红布树需要额外指针,内存碎片化 | | **冲突解决效率** | 简单但可能频繁扩容(负载因子 2/3) | 链表 O(1)/红布树 O(logn) | | **适用场景** | 预期数据量小(线程隔离变量通常少) | 通用场景,支持大数据量 | **为什么 ThreadLocal 使用线性探测?** - **轻量级**:ThreadLocal 通常存储少量线程本地变量,线性探测简单高效。 - **避免内存泄漏**:弱引用 Key 需及时清理,开放地址法更容易触发清理逻辑(`expungeStaleEntry`)。 --- ### 二、LeetCode 236二叉树最近公共祖先LCA) --- #### 1. **问题描述** 给定一个二叉树和两个节点 `p`、`q`,找到它们的最近公共祖先(最低层级的共同祖先)。 #### 2. **递归解法** ```python def lowestCommonAncestor(root, p, q): if not root or root == p or root == q: return root left = lowestCommonAncestor(root.left, p, q) right = lowestCommonAncestor(root.right, p, q) if left and right: # p 和 q 分布在两侧 return root return left if left else right # 返回非空的一侧 ``` #### 3. **关键点** - **后序遍历**:自底向上查找,先处理子树再判断当前节点。 - **终止条件**:当前节点是 `p` 或 `q`,或为空。 - **合并结果**:若左右子树均找到目标,当前节点是 LCA;否则返回非空子树的结果。 #### 4. **复杂度** - 时间复杂度:O(n),每个节点遍历一次。 - 空间复杂度:O(h),递归栈深度(h 为树高)。 --- ### 总结 - **ThreadLocal**:通过线性探测的轻量级设计实现线程隔离变量存储。 - **LCA 问题**:递归后序遍历是典型解法,需理解“合并子树结果”的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值