day21|二叉树day7-二叉搜索树的最小绝对差,众数

利用中序遍历解决二叉搜索树的问题。

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

在这里插入图片描述

二叉树遍历的双指针操作

class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        # 利用
        st = []
        p = root
        pre = -float('inf')
        min_val = float('inf')
        # 利用双指针,使得pre紧跟cur的值
        while p is not None or st:
            while p is not None:
                st.append(p)
                p = p.left
            p = st.pop()
            cur = p.val
            if cur - pre < min_val:
                min_val = cur - pre
            pre = cur # 上一个节点的值
            p = p.right
        return min_val
# 伪代码
result = Max_len # 用全局变量记录相邻结点的最小值,递归函数中直接修改全局参数即可,所以递归函数不需要有返回值
pre = TreeNode()
def traversal(cur):
	if not cur:
		return 
	traversal(cur.left) # 左
	if pre:             # 中
		result = min(result,cur.val-pre.val)
	# pre如何紧跟着cur成为cur的前一个节点
	pre = cur
	# 右
	traversal(cur.right)
	

我的思路(直白想法):
由于是二叉搜索树,所以可以利用中序遍历将二叉搜索树变成递增的序列,然后利用双指针的方式找到对应的最小差值。

class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        # 按照左中右的中序顺序进行遍历
        result = []
        def dfs(node,result):
            if not node:
                return 
            dfs(node.left,result)
            if node:
                result.append(node.val)
            dfs(node.right,result)
            return result
        result = dfs(root,result)
        minValue = float('inf')
        i,j = 0,1 # 利用双指针找到差值最小
        while j <= len(result)-1:
            if minValue > result[j] - result[i]:
                minValue = result[j] - result[i]
            i += 1 
            j += 1
        return minValue

501. 二叉搜索树中的众数

双指针的思路:如果pre和cur相等那么对应的元素重复次数+1
反思: 全局变量需要以类内变量的形式出现

class Solution:
    def __init__(self):
        self.pre = TreeNode()
        self.count = 0
        self.max_count = 0
        self.result = []
    def search_BST(self, cur: TreeNode) -> None:
        if not cur: 
            return None
        self.search_BST(cur.left)
        # 第一个节点
        if not self.pre:
            self.count = 1
        # 与前一个节点数值相同
        elif self.pre.val == cur.val:
            self.count += 1 
        # 与前一个节点数值不相同
        else:
            self.count = 1
        self.pre = cur

        if self.count == self.max_count:
            self.result.append(cur.val)
        
        if self.count > self.max_count:
            self.max_count = self.count
            self.result = [cur.val]	# 清空self.result,确保result之前的的元素都失效
    
        self.search_BST(cur.right)
    def findMode(self, root: TreeNode) -> List[int]:
        if not root: 
            return None
        self.search_BST(root)
        return self.result

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

在这里插入图片描述
回溯: 需要将左右叶子结点中是否有p和q传入上一个结点中,左右子树都不为空则当前的父结点即为公共祖先。
那么如果采用回溯的方法,需要使用左右中后序遍历的方式。两种情况p&q是否在同一个枝叶的路径上。

// C++伪代码
TreeNode* traversal(root,q,p){
	if(root==null) return null; // 如果遇到根节点直接返回
	if(root==p || root==q): return root;
	left = traversal(root.left,p,q) //告诉我们左子树中有没有出现p和q
	right = traversal(root.right,p,q) //告诉我们左子树中有没有出现p和q
	if left!= null && right != null:
		return root //此时为公共祖先
	if (left==null && right != null): //把右子树向上返回
		return right;
	else(right==null && left != null):
		return left;
		
}

基本思路:返回左子树和右子树中是否出现过p或者q,如果出现过则把当前的这个结点返回给上一层结点。

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        def traversal(root,p,q):
      =
            if not root:
                return None
            if root == p or root == q:
                return root
            left = traversal(root.left,p,q)
            right = traversal(root.right,p,q)
            if left and right:
                return root
            # 非常关键的一步,不容易想。将含有两个结点的根结点传入上一层结点中,而不是任何时候传入的都是根节点。
            if not left and right : return right
            elif left and not right : return left
            else: return None
        return traversal(root,p,q)

补充:python知识点

python的字典排序

将python转化成元组类型的数据类型,然后使用sorted函数对元组列表进行排列即可。

d = {'a':1,'c':3,'b':2}
# d.items() 的返回值是dict_items([('a',1),('c',3),('b',2)])
# key表示按照哪一列进行排序
d_order = sorted(d.items(),key=lambda x:x[1],reverse = False)
print(d_order)

python中的局部变量与全局变量

函数中生成的变量均为局部变量,如果想要使用全局变量,需要将变量当成类内的属性。

  1. 局部变量: 当搜索一个标识符时,Python先从局部作用域开始搜索。如果在局部作用域内没有找到那个名字,那么一定会在全局域找到这个变量,否则会被抛出NameError异常。
  2. 全局变量: 全局变量的一个特征是除非删除掉,否则它们存活到脚本运行结束,且对于所有的函数,它们的值都是可以被访问的。

在函数中声明global函数即可达到,让函数中的变量成为全局变量的作用,此时改变函数体中的变量,相应的其他变量也会发生改变。

情况1: 外部没有定义x的值报错
在这里插入图片描述
情况2: 内部如果声明全局变量则此时不报错
在这里插入图片描述

情况3: 内部没有定义b就对b进行了运算故报错
在这里插入图片描述
情况4:在函数中声明全局变量,此时对应的函数不报错。
在这里插入图片描述
情况5: nonlocal声明在上级的局部作用域中,而不是全局定义,比如说在嵌套函数的情况下,利用nonloacl可以使得内部的变量作用到向外一层的函数中,但是如果声明的变量在上级局部变量中不存在,则会报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值