更弱智的算法学习 day18

530.二叉搜索树的最小绝对差

一开始想错了,想着对于二叉搜索树来说,最小差值肯定在父节点和左右子节点之间产生,实际上,根据搜索树的性质,其中序遍历就是一个递增数组,直接在数组中处理就可以了

在递归过程中,用户在每个节点处只计算了当前节点与左右子节点的差的绝对值,但实际上,在二叉搜索树中,最小差值不一定出现在父子节点之间,也可能出现在祖先和后代之间,但由于二叉搜索树的性质,最小差值一定出现在相邻的中序遍历节点之间。

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.maxdiff = 10**5+1
        self.res = []
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        self.traversal(root, self.res)
        for i in range(len(self.res)-1):
            diff = self.res[i+1] - self.res[i]
            self.maxdiff = min(diff, self.maxdiff)
        return self.maxdiff

    def traversal(self, root, res):
        if not root:
            return
        self.traversal(root.left, res)
        self.res.append(root.val)
        self.traversal(root.right, res)
        
        

501.二叉搜索树中的众数

这个题目可以转化为收集到中序的序列数据,然后对此序列寻找众数。然而如何寻找众数呢?

  • self.res[i] == self.res[i-1]时,说明当前数值与前一个相同,current_count加1。

  • 当遇到一个不同的数值时,说明前一个数值的连续序列结束了。此时,调用 update_modes方法来判断这个刚刚结束统计的数值是否是众数

  • update_modes方法根据当前数值的计数 (count) 与当前已知的最大计数 (self.maxcount) 进行比较:

    如果 count > self.maxcount:这意味着发现了出现次数更多的数。此时,将 self.maxcount更新为这个更大的 count,并清空之前的众数列表 self.out,然后将这个新的众数 val加入列表。

    如果 count == self.maxcount:这意味着发现了一个出现次数和当前众数一样多的数。此时,只需将这个数 val追加到众数列表 self.out中即可。

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.res = []
        self.maxcount = 0
        self.out = []


    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        self.traversal(root,self.res)
        current_val = self.res[0]
        current_count = 1

        for i in range(1, len(self.res)):
            if self.res[i] == self.res[i-1]:
                current_count += 1
            else:
                self.update_modes(current_val, current_count)
                current_val = self.res[i]
                current_count = 1
        self.update_modes(current_val, current_count)

        return self.out

    def update_modes(self, val, count):
        """更新众数列表"""
        if count > self.maxcount:
            self.maxcount = count
            self.out = [val]  # 清空之前的结果,重新开始
        elif count == self.maxcount:
            self.out.append(val)  # 相同频率,追加到结果

    def traversal(self, root, res):
        if not root:
            return
        self.traversal(root.left, res)
        self.res.append(root.val)
        self.traversal(root.right, res)

学习了一下不需要额外空间的写法,感觉总体来说区别不太大。

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.max_count = 0
        self.cur_count = 0
        self.pre_value = None
        self.res = []

    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        self.traversal(root)
        return self.res

    def traversal(self, root):
        if not root:
            return
        self.traversal(root.left)

        if root.val != self.pre_value: #与前一个节点不同的情况
            self.cur_count = 1
            self.pre_value = root.val
        else:
            self.cur_count += 1
        
        if self.cur_count > self.max_count:
            self.res = [root.val]
            self.max_count = self.cur_count
        elif self.cur_count == self.max_count:
            self.res.append(root.val)
        
        self.traversal(root.right)

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

总体思想比较好懂,也即分类讨论。

考虑p和q的位置,如果从当前节点看,p和q分别在左右子树里,那么最近公共祖先就是自己,也即root;如果仅左子树或右子树有,那么在存在的那一侧返回;如果都不存在,则返回None,表示既没找到p和q,也算不出最近公共祖先。

复杂的点在于返回值的异质性,即返回"有没有找到p和q",也返回"有没有算出最近公共祖先",理解是当左右子树返回都是非空节点时,此时返回的就是最近公共祖先,再次之前,返回的都是,这里是否有p或q的判断

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root:
            return None

        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)

        if root == p or root == q or left and right:
            return root
        if right:
            return right
        if left:
            return left

补充一下二叉搜索树的最近公共祖先

二叉搜索树的最近公共祖先由于大小排序,可以轻松知道本节点视角下的p和q的位置

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        value = root.val
        if p.val < value and q.val < value:
            return self.lowestCommonAncestor(root.left, p, q)
        elif p.val > value and q.val > value:
            return self.lowestCommonAncestor(root.right, p, q)
        else:
            return root
相关推荐
Morwit2 分钟前
【力扣hot100】 1. 两数之和
数据结构·c++·算法·leetcode·职场和发展
嵌入式小企鹅9 分钟前
蓝牙学习系列(八):BLE L2CAP 协议详解
网络·学习·蓝牙·ble·协议栈·l2cap
无小道32 分钟前
算法——暴力+优化
算法·优化·暴力
Free Tester36 分钟前
如何判断 LeakCanary 报告的严重程度
java·jvm·算法
zyq99101_11 小时前
DFS算法实战:经典例题代码解析
python·算法·蓝桥杯·深度优先
jiayong231 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习
智者知已应修善业1 小时前
【51单片机单按键切换广告屏】2023-5-17
c++·经验分享·笔记·算法·51单片机
广州灵眸科技有限公司1 小时前
为RK3588注入澎湃算力:RK1820 AI加速卡完整适配与评测指南
linux·网络·人工智能·物联网·算法
qinian_ztc1 小时前
frida 14.2.18 安装报错解决
算法·leetcode·职场和发展
AI应用实战 | RE1 小时前
012、检索器(Retrievers)核心:从向量库中智能查找信息
人工智能·算法·机器学习·langchain