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

目录

Leetcode - 530

Leetcode - 501

Leetcode - 236


Leetcode - 530

暴力法就是先中序遍历出一个序列,然后用双指针求相邻元素差的绝对值。

def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        res = []
        def traversal(root):
            nonlocal res
            if not root:
                return None
            
            traversal(root.left)
            res.append(root.val)
            traversal(root.right)
        traversal(root)
        
        minValue = float("INF")
        i  =0
        j = i+1
        while j < len(res):
            gap  = abs(res[j] - res[i])
            if gap < minValue:
                minValue = gap
            j+=1
            i+=1
            
        return minValue

另一个方法,递归,对于这种二叉搜索树,依然用中序遍历,此处是定义一个node来指向root的上一个节点,然后让node和root的值做差并记录,和验证二叉树那题的思路一样

def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        minGap = float("INF")
        node = None
        def traversal(root):
            nonlocal node,minGap
            if not root:
                return 

            traversal(root.left)

            if node != None:
                minGap = min(minGap,abs(node.val - root.val))
            node = root

            traversal(root.right)
       
        traversal(root)
        return minGap

Leetcode - 501

首先是暴力法,先中序遍历,然后统计词频再返回结果,很简单,代码就不放了。

另一种 递归法,这里首先说几个全局变量,count用于记录当前节点的频数,maxCount用于记录最大频数,res用于存结果,node用于指向root的上一个节点。

这里首先要注意的是  此处记录频数不能使用node来记录,要使用root指向的节点来统计频数,若使用node记录,则会忽略掉树中的最后一个节点。  再就是count>maxCount时,res要清空。

还有遇到node.val != root.val时,因为是用root来记录节点,所以此时要将count重新置为1,用于为新的一个节点记录频数。

这里三点我都想到了,但是还是没能ac,重点就是一开始,node==None时的逻辑,此时node和root没法进行比较,这里直接count = 1即可,为第一个节点计数。当node.val==root.val时,count+=1,当两者不等时,重置count=1,注意这里的三个条件是平行的

当这些进行完后,再进行count和maxCount的比较,若count小 不管,两者相等,append,count更大,清空res,并append root.val ,然后跟新maxCount的值

def findMode(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        count = 0
        maxCount = 0
        node = None

        def traversal(root):
            nonlocal count,maxCount,res,node
            if not root:
                return

            traversal(root.left)
            if node == None:
                count = 1
            elif node.val == root.val:
                count += 1
            elif node.val != root.val:
                count = 1

            if count == maxCount:
                res.append(root.val)
            elif count > maxCount:
                res = []
                res.append(root.val)
                maxCount = count
            
            node = root
            traversal(root.right)

        traversal(root)
        return res

Leetcode - 236

首先确定遍历顺序,这题是找两个节点的最近公共祖先,那肯定是从下往上的,从下往上就是后序遍历,这题是返回祖先,所以递归是有返回值的,且进行左右遍历的时候肯定都需要定义一个变量来接收结果,递归终止的时候也需要返回值,这里要和没有返回值的递归区分开,没有返回值时左右子树遍历还有递归终止(直接return就行)都不需要返回值

首先  递归函数参数: root,p,q

终止条件: root为空直接return root(None),若root为p,q其中一个直接返回root。

然后是左右子树递归,返回值分别用left和right接受,再到中的处理逻辑:若left和right同时不为空说明当前的root就是我们要求的最近公共祖先,若left和right其中有一个不为空,那么将这一个返回,若同时为空返回None。

这里分两种情况讨论:1. p,q分别在不同子树上,left和right分别是在root的左子树和右子树中递归返回的结果,若均不为空,则说明能在两个子树中将这两个节点找到,又因为是从下往上遍历的,所以这里root就是最近的公共祖先。  2 p是q的祖先或者q是p的祖先,这里以p为祖先为例,p会先被找到所以会被先作为结果返回,直接用P向上传递。

def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':

        def traversal(root,p,q):
            if root == None:
                return root
            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
            elif left == None and right != None:
                return right
            elif left !=None and right == None:
                return left
            else:
                return None

        return traversal(root,p,q)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值