代码随想录算法训练营第二十一天

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

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

题目链接:二叉搜索树的最小绝对差

双指针

这道双指针的两根指针运动的轨迹是中序遍历(左中右),pre指针一直尾随cur指针。这里尾随,因为是左中右的原因,中和左右,以及中和右左,也只是会比较到的,由于是二叉搜索树,所以只比较相邻的两个node之间的差就够了(中-左,右-中)。例子

def traverse(root):
	nonlocal result, pre
	if not root:
		return
	traverse(root.left)
	if pre:
		result = min(result,root.val-pre.val) #顺序是左中右,pre跟着root所以不用abs
	pre = root
	traverse(root.right)

中序遍历,
最里层,root直接一路走到左下角的1,然后1的left是None,无事发生,此时pre也是None,不进if pre,之后让pre = 1这个node,1的right是None,继续无事发生。
往上一层,root是2,root.left走过了,此时pre是1,所以进if pre,得到result=2-1=1,然后pre变成2
root.right是3,也可以得到result=3-2=1,pre变成3
再上一层,root是4,但此时pre是3,所以这里还是可以得到4-3这个结果的!!
这也是昨天验证二叉搜索树里可以解决陷阱的原因。
视频解析:卡哥牛逼

class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        pre = None
        result = inf
        def traverse(root):
            nonlocal result, pre
            if not root:
                return
            traverse(root.left)
            if pre:
                result = min(result,root.val-pre.val) #顺序是左中右,pre跟着root所以不用abs
            pre = root
            traverse(root.right)
        
        traverse(root)
        return result

普通递归

用前序(左中右)把所有node收集到一个list里,然后找相邻元素的最小值。

class Solution(object):
    def getMinimumDifference(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        def traverse(root):
            if not root:
                return
            traverse(root.left)
            res.append(root.val)
            traverse(root.right)
        
        res = []
        traverse(root)
        result = float("inf")
        for i in range(len(res)-1):
            result = min(result,(res[i+1]-res[i]))
        return result

迭代

class Solution(object):
    def getMinimumDifference(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        queue = collections.deque()
        queue.append(root)
        cur = root
        pre = None
        result = float("inf")
        while queue:
            while cur.left:
                cur = cur.left
                queue.append(cur)
            cur1 = queue.pop()
            if pre:
                result = min(result,cur1.val-pre.val)
            pre = cur1
            if cur1.right:
                cur = cur1.right
                queue.append(cur)
        return result

501. 二叉搜索树中的众数

题目链接:二叉搜索树中的众数

普通二叉树的众数

class Solution:
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        d = defaultdict(int)
        def traverse(root):
            nonlocal d
            if not root:
                return
            traverse(root.left)
            d[root.val] += 1
            traverse(root.right)
        traverse(root)
        l = max(d.values())
        re = []
        for i in d:
            if d[i] == l:
                re.append(i)
        return re

搜索二叉树的众数

用双指针遍历整个树,如果pre和cur的值相等,那么计数,如果不等就重新开始新的计数,初始设定maxcount是1,如果数到count和maxcount一样大的那么就计入此刻的root,如果比maxcount大的就重置list再放此刻的root。

class Solution:
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        count = 1
        maxcount = 1
        pre = None
        res = []
        def traversal(root):
            nonlocal count, maxcount, pre, res
            if not root:
                return
            traversal(root.left)
            if pre and (pre.val == root.val):
                count += 1 #计数
            elif pre and (pre.val != root.val):
                count = 1 #count重置
            pre = root
            if count == maxcount:
                res.append(root.val)
            elif count > maxcount:
                res = []
                maxcount = count
                res.append(root.val)
            traversal(root.right)
        traversal(root)
        return res

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

题目链接:二叉树的最近公共祖先
这里的逻辑是往树的两边找p和q,找到的话就往上传,用后序遍历(左右中),所以就是self.lowestCommonAncestor(root.left,p,q)self.lowestCommonAncestor(root.right,p,q),root是被传进去的,所以自己没有改变,还是根节点,所以如果左右都找到了就可以输出根节点,一边找到了另一边没有就说明一边找到的那个就最近公共祖先,所以直接输出就行了。

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root:
            return root
        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
        if (not right) and left:
            return left      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值