首页 > 其他分享 >day20| 654+617+700+98

day20| 654+617+700+98

时间:2023-04-07 12:34:54浏览次数:41  
标签:right val nums 700 98 654 root 节点 left

654. 最大二叉树

 

题目简述:

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。

 

思路

 

利用递归

1. 创建root,类型为TreeNode,值为传入数组中的最大值

2. 设置它的左右节点为递归函数的返回值,递归函数的输入为一个区间范围

3. 设置停止条件,当left>=right,区间内不在有数值,返回None

 

代码如下:

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        def dfs(left,right):
            if left>=right:
                return None
            max_num=max(nums[left:right])
            index_max=nums.index(max_num)
            root=TreeNode(max_num)
            root.left=dfs(left,index_max)
            root.right=dfs(index_max+1,right)
            return root
        
        root=dfs(0,len(nums))
        return root

 

利用字典来存储数组中各个数的下标值,貌似能跑得更快

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        dict={}
        n=len(nums)
               
        for i in range(n):
            dict[nums[i]]=i
        
        def dfs(left,right,array):
            if left>=right:
                return None            
            max_nums=max(array)
            max_index=dict[max_nums]
            root=TreeNode(max_nums)
            root.left=dfs(left,max_index,nums[left:max_index])
            root.right=dfs(max_index+1,right,nums[max_index+1:right])
            return root
        
        ptr1=dfs(0,n,nums)
        return ptr1

 

 

巧妙方法:单调栈实现

1. 一次遍历实现,一边遍历一边创建节点并设置左右孩子

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        stack=[]
        for num in nums:
            cur=TreeNode(num)
            while stack and stack[-1].val<num:
                cur.left=stack.pop()
            if stack:# mean stack[-1].val>num
                stack[-1].right=cur
            
            # 运行至此,意味着stack为空 或者 stack不为空但是stack[-1].val>num并设好了对应右指针参数,此时可以把num加进stack中
stack.append(cur) return stack[0]

 

2. 先创建两个列表,分别存有左边和右边第一个更大值的信息,相当于两个单调栈,然后再重新遍历组建树

 

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        n = len(nums)
        stk = list()
        left, right = [-1] * n, [-1] * n
        tree = [None] * n

        for i in range(n):
            # 每遍历一个值,都创建一个节点
            tree[i] = TreeNode(nums[i])
            while stk and nums[i] > nums[stk[-1]]:
                # 对于下标为stk[-1]的元素,右边第一个比他大的元素的下标为i,这是典型的单调栈
                right[stk[-1]] = i
                stk.pop()
            if stk:
                # 对于下标为i的元素,左边第一个比他大的元素的下标为stk[-1],这是典型的单调栈
                left[i] = stk[-1]
            stk.append(i)
        
        root = None
        for i in range(n):
            if left[i] == right[i] == -1:
                root = tree[i]
            
            # 1. right[i]==-1 and left[i]!=-1,意味着nums[i]是只有左边有比他大的值或者nums[i]在最右边
            # 2. 或者right[i]!=-1 and left[i]!=-1,并且nums[left[i]] < nums[right[i]]),意味着左右都有比他大的,且左边的小于右边的,右边有更大值
            elif right[i] == -1 or (left[i] != -1 and nums[left[i]] < nums[right[i]]):
                # 先不管,就令左边最大值的右孩子为当前下标对应节点
                tree[left[i]].right = tree[i]
            
            # 1. right[i]!=-1 and left[i]==-1,右边有更大的值,左边却没有。
            else:
                # 此时把右边最大值的左孩子设为当前节点
                tree[right[i]].left = tree[i]
        
        return root

 

617. 合并二叉树

 

题目简述:

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

 

思路:

利用层序遍历,挨个相加即可,对节点存在与否进行细致分类讨论

class Solution:
    def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode:
        if not t1:
            return t2
        if not t2:
            return t1
        
        merged = TreeNode(t1.val + t2.val)
        queue = collections.deque([merged])
        queue1 = collections.deque([t1])
        queue2 = collections.deque([t2])

        while queue1 and queue2:
            node = queue.popleft()
            node1 = queue1.popleft()
            node2 = queue2.popleft()
            left1, right1 = node1.left, node1.right
            left2, right2 = node2.left, node2.right
            if left1 or left2:
                if left1 and left2:
                    left = TreeNode(left1.val + left2.val)
                    node.left = left
                    queue.append(left)
                    queue1.append(left1)
                    queue2.append(left2)
                elif left1:
                    node.left = left1
                elif left2:
                    node.left = left2
            if right1 or right2:
                if right1 and right2:
                    right = TreeNode(right1.val + right2.val)
                    node.right = right
                    queue.append(right)
                    queue1.append(right1)
                    queue2.append(right2)
                elif right1:
                    node.right = right1
                elif right2:
                    node.right = right2
        
        return merged

 

700. 二叉搜索树中的搜索

题目简述:

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

 

思路:

递归实现

class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        if root is None:
            return None
        if val == root.val:
            return root
        return self.searchBST(root.left if val < root.val else root.right, val)

 

98. 验证二叉搜索树

 

题目简述:

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

 

思路:

 

递归:

1. 一个树要是二叉搜索树,那么对于他的一个节点来说,节点的值必须大于左孩子值小于右孩子值并且左孩子和右孩子都得是二叉搜索树

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        def helper(node, lower = float('-inf'), upper = float('inf')) -> bool:
            if not node:
                return True
            
            val = node.val
            if val <= lower or val >= upper:
                return False

            if not helper(node.right, val, upper):
                return False
            if not helper(node.left, lower, val):
                return False
            return True

        return helper(root)

 

 

遍历,中序遍历

1. 二叉搜索树的中序遍历是单调递增的,利用这个性质

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        stack, inorder = [], float('-inf')
        
        while stack or root:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            # 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
            if root.val <= inorder:
                return False
            inorder = root.val
            root = root.right

        return True

 

 

 

总结:

1. 熟练掌握递归

2. 了解单调栈

3. 熟练掌握各种遍历

 

标签:right,val,nums,700,98,654,root,节点,left
From: https://www.cnblogs.com/cp1999/p/17295761.html

相关文章

  • DS4700/DS4800 存储巡检
    DS4800——(M02,连B控1口)192.168.128.100ping192.168.128.102DS4700——(O07,M04)port1B控192.168.128.102/241.安装点击0035.exe,简体中文(ok),next,next,accept(next),选择路径(next),Typical(next),Automaticallystartmonitor(next),install,Done2.连接3.查看......
  • L298N驱动板使用
                    引脚功能ENA,ENB使能端,输入PWM信号IN1,IN2电机A输入端,TTL逻辑电平信号OUT1,OUT2电机A输出端,与对应输入端同逻辑IN3,IN4电机B输入端,TTL逻辑电平信号OUT3,OUT4电机B输出端,与对应输入端同逻辑VCC(12V)+12V输......
  • COMP3411/9814 人工智能
    COMP3411/9814ArtificialIntelligenceTerm1,2023Assignment3–PlanningandMachineLearningDue:Week10-10pmFriday21AprilMarks:10%offinalassessmentforCOMP3411/9814ArtificialIntelligenceQuestion1:Planning(4marks)Modifythesimpleplanner......
  • 代码随想录Day20-Leetcode654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验
    654.最大二叉树题目链接:https://leetcode.cn/problems/maximum-binary-tree/基本的模拟思路很快/***Definitionforabinarytreenode.*functionTreeNode(val,left,right){*this.val=(val===undefined?0:val)*this.left=(left===undefined......
  • 技嘉 B360 HD3 Core i7-8700 GTX1060黑苹果efi引导文件
    原文来源于黑果魏叔官网,转载需注明出处。(下载请直接百度黑果魏叔)硬件型号驱动情况主板技嘉B360HD3(B360芯片组)处理器英特尔[email protected]六核已驱动内存32GB(现代DDR42666MHz16GB/金邦DDR43000MHz16GB)已驱动硬盘技嘉GP-GSTFS31120GNTD(120GB/固态硬......
  • ASEMI代理AD7980BRMZRL7原装ADI(亚德诺)车规级AD7980BRMZRL7
    编辑:llASEMI代理AD7980BRMZRL7原装ADI(亚德诺)车规级AD7980BRMZRL7型号:AD7980BRMZRL7品牌:ADI/亚德诺封装:MSOP-10批号:2023+安装类型:表面贴装型AD7980BRMZRL7汽车芯片AD7980BRMZRL7特征高性能伪差分模拟输入范围0V至VREF,VREF在2.5V至5V之间吞吐量:1MSPS零延迟架构16......
  • 2022-适用于 Windows 10 Version 1809 的 02 累积更新,适合基于 x64 的系统 (KB5010351
    2022-适用于Windows10Version1809的02累积更新,适合基于x64的系统(KB5010351)-错误0x800f0982系统是win10企业版LTSC版本可能安装的是精简版导致的运行疑难解答这个方案无效利用win10更新助手-因为是企业版TLSC版本所以用不了WIN10LTSC版更新失败如何解决?这......
  • 洛谷 P2398. GCD SUM
    题目描述求$$\sum\limits_{i=1}^n\sum\limits_{j=1}^n\gcd(i,j)$$输入:2输出:5算法1 线性筛 $O(n)$将式子变形:要知道一个前置定理$\sum\limits_{d|n}\varphi(d)=n$艾弗森约定:定义$\\\[P]$=$$\begin{cases}P\text{}is\text{}tr......
  • P2986 Great Cow Gathering G
     换根dp,father->son ,基本是加减 #include<bits/stdc++.h>usingnamespacestd;constintN=1e5+2,M=N*5;#defineintlonglongintn,a[N],sz[N],g[N],f[N],S;intnxt[M],go[M],w[M],hd[N],all;voidadd(intx,inty,intz){ go[++all]=y,nxt[a......
  • 笔记:洛谷 P3985 不开心的金明
    算法笔记:[背包问题]洛谷P3985不开心的金明题目详情原题链接:洛谷P3985不开心的金明不开心的金明Description  金明今天很不开心,家里购置的二手房就要领钥匙了,房里并没有一间他自己专用的很宽敞的房间。更让他不高兴的是,妈妈昨天对他说:“你需要购买哪些物品,怎么布置,你......