代码随想录算法训练营第二十天|654.最大二叉树、 617.合并二叉树、700.二叉搜索树中的搜索 、98.验证二叉搜索树

目录

Leetcode - 654

Leetcode - 617

Leetcode - 700

Leetcode - 98


Leetcode - 654

这题和104 105通过前中后序构建二叉树的套路是一样的,

递归条件终止条件:序列为空返回None

先求一个最大值节点作为根节点,查找根节点的位置,对序列进行划分,划分为左右子树,分别对左右子树递归,最后返回根节点

def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        def constructTree(nums):
            if nums == []:
                return None

            rootVal = max(nums)
            root = TreeNode(rootVal)

            index = nums.index(rootVal)
            leftChild = nums[:index]
            rightChild = nums[index+1:]

            root.left = constructTree(leftChild)
            root.right = constructTree(rightChild)

            return root

        return constructTree(nums)

Leetcode - 617

这题使用先序遍历更符合逻辑,关键就在于确定递归的终止条件,首先要明确地是,两棵树是同时进行遍历的,遍历到的节点是同步的,对节点分为三种情况讨论:1. 第一棵树对应的该节点为空 2.第二棵树对应的该节点为空  3. 两个节点均不为空。

针对1,2情况 写出递归终止:如果第一棵树节点为空,返回第二棵树相应的节点。如果第二棵树节点为空,返回第一棵树相应的节点。这里其实包含了左右两树相应节点均为空的情况,若同时为空则返回None,以上条件是囊括了这种情况

当同时不为空时,又分两种写法,第一种是打算直接以第一棵树作为结果返回的,此处直接对第一棵树的节点的val做加法即可。此处完成了“中”,接着进行“左右”,注意此处左右遍历后的结果分别作为第一棵树的左子树和右子树

def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        def merge(root1,root2):
            if not root1:
                return root2

            if not root2:
                return root1

            root1.val += root2.val
            
            root1.left = merge(root1.left,root2.left)
            root1.right = merge(root1.right,root2.right)

            return root1

        return merge(root1,root2)

第二种写法是新定义一颗树

def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        def merge(root1,root2):
            if not root1:
                return root2

            if not root2:
                return root1

            root1.val += root2.val
            
            root1.left = merge(root1.left,root2.left)
            root1.right = merge(root1.right,root2.right)

            return root1

        return merge(root1,root2)

Leetcode - 700

直接while循环遍历,到节点为空前还没找到就返回False

def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        
        
           
            while root:
                if root.val == val:
                    return root
                elif root.val < val:
                    root = root.right
                else:
                    root = root.left
            else:
                return None

递归写法:

终止条件是重点:两个 若节点到None,代表没找到,返回None,也就是返回root,另一种是找到了 返回root

若当前节点值大于target,则遍历左子树,否则遍历右子树

def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        
        def search(root,val):
           
            if not root or root.val == val: 
                return root

            if root.val > val: 
                return self.searchBST(root.left, val)

            else: 
                return self.searchBST(root.right, val)
                

        return search(root,val)
       

Leetcode - 98

由于二叉搜索树,在进行中序遍历的时候,得出的序列是有序的,所以可以先得出中序遍历的序列再判断是否有序即可,注意 遇到二叉搜索树 就考虑中序

def isValidBST(self, root: Optional[TreeNode]) -> bool:
        
#中序遍历
        res =[]
        def traversal(node):
            if node == None:
                return

            traversal(node.left)
            res.append(node.val)
            traversal(node.right)

        traversal(root)
      #判断序列是否有序  
        i =0
        j =i+1
        while j <len(res):
            if res[j] <= res[i]:
                return False
            else:
                i+=1
                j+=1

        else:
            return True

递归的做法,首先定义一个全局变量 maxValue 初始化为-float("INF"),

终止条件为节点为空,此处是return True因为空树满足任何树的定义,空树也是二叉搜索树

这里依然是中序,先是左子树,返回一个bool值,在就是中间,因为是有序的,所以当前节点的值大于maxValue才合理,接着跟新maxValue为当前值,否则返回False,再就是右子树,要同时满足左右子树均为二叉搜索树才行

def isValidBST(self, root: Optional[TreeNode]) -> bool:
        
        maxValue = -float("INF")
        def check(root):
            nonlocal maxValue

            if not root:
                return True

            checkLeft = check(root.left)

            if maxValue < root.val:
                maxValue = root.val
            else:
                return False

            checkRight = check(root.right)

            return checkLeft and checkRight

        return check(root)

此外,这里可以不用跟新最大值的方法,可以使用双指针,利用一个指针指向上一个节点,先初始化一个指针为None,再每一轮中序遍历中,将root赋值给这个指针,那么在每一轮赋值之前,这个指针都指向上一个节点,通过上一个节点的值与当前root的值判断即可,保证上一个节点值小于当前root,否则返回False

def isValidBST(self, root: Optional[TreeNode]) -> bool:
        
        # maxValue = -float("INF")
        node = None
        def check(root):
            nonlocal node

            if not root:
                return True

            checkLeft = check(root.left)

            if node!=None:
                if node.val >= root.val:
                    return False

            node = root

            checkRight = check(root.right)

            return checkLeft and checkRight

        return check(root)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值