代码随想录算法训练营day21|530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

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

代码随想录

视频讲解:二叉搜索树中,需要掌握如何双指针遍历!| LeetCode:530.二叉搜索树的最小绝对差_哔哩哔哩_bilibili

把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了

递归法(版本一)利用中序递增,结合数组

# 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.vec = []
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        self.vec=[]
        self.traversal(root)
        if len(self.vec) < 2:
            return 0
        result = float('inf')
        
        for i in range(1,len(self.vec)): #可以优化为:for i in range(1,len(self.vec)):
                                                         #result = min(result,abs(self.vec[i]-self.vec[i-1]))
            r = abs(self.vec[i]-self.vec[i-1])
            if r

递归法(版本二)利用中序递增,找到该树最小值

# 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.result = float('inf')
        self.pre = None
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        self.traversal(root)
        return self.result

    def traversal(self,cur):    
        if not cur:
            return 

        self.traversal(cur.left)
        
        if self.pre != None:
            self.result = min(self.result,abs(self.pre.val-cur.val))  
        self.pre = cur
        self.traversal(cur.right)

 501.二叉搜索树中的众数 

使用字典

# 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.result = []
        self.fre_dic = {}

    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        self.result = []
        self.fre_dic = {}
        self.traversal(root)
        max_fre = max(self.fre_dic.values())

        for key,value in self.fre_dic.items():
            if value == max_fre:
                self.result.append(key)
        return self.result
    
    def traversal(self,cur):
        if not cur:
            return None
        
        self.traversal(cur.left)

        if cur.val not in self.fre_dic.keys():
            self.fre_dic[cur.val] = 1
        else:
            self.fre_dic[cur.val] += 1

        self.traversal(cur.right)

双指针法

# 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.result = []
        self.max_count = 0
        self.pre = None 
        self.count = 0

    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        self.result = []
        self.max_count = 0
        self.pre = None 
        self.count = 0

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

        if self.pre == None:
            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.traversal(cur.right)

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

代码随想录

视频讲解:自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先_哔哩哔哩_bilibili

回溯,二叉树回溯的过程就是从低到上。

后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。

后序遍历:

# 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
        if root == p or root == q:
            return root 

        left = self.lowestCommonAncestor(root.left,p,q)
        right = self.lowestCommonAncestor(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

这道题感觉有点难懂

总结:

  1. 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。

  2. 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。

  3. 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。

你可能感兴趣的:(算法)