Treeddddddd

树的递归遍历----深度优先搜索

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

preorder---中左右

postorder---左右中

inorder---左中右

144. Binary Tree Preorder Traversal

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root ==  None:
            return []
        return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + [root.val]

层序遍历----广度优先搜索

102. Binary Tree Level Order Traversal

二叉树本身的结构做不到,借助--队列--数据结构

tip: 数组元素倒叙输出:res[::-1]

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root is None:
            return []
        # 1. 建一个队列,并把root放进去
        queue = collections.deque([root])
        result = [] # 最终结果

        while queue:
        # 2. 大循环----一层一个循环
            level = []
            size = len(queue)

            # 3. 小循环: 
            # a. queue最左边的元素pop
            # b. append进level
            # c. 该元素的左右孩子add进queue
            # 结束: size为0

            while size:
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
                size -= 1
            result.append(level)
        return result
        

104. Maximum Depth of Binary Tree

层序遍历法


翻转二叉树

将当前节点的左右child调换

选择前序遍历

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return None
        # preorder
        # 中
        root.left, root.right = root.right, root.left

        # 左
        self.invertTree(root.left)

        # 右
        self.invertTree(root.right)

        return root

对称二叉树

101. Symmetric Tree

后序遍历---通过左右孩子的情况反馈给root

对当前root,它的左右子树是对称的---> 返回给root true的信息

怎么判断左右子树对称:left.left和right.right一样, left.right和right.left一样

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if root is None:
            return True
        return self.compare(root.left, root.right)
    def compare(self, left, right):
        # 比较某个root的左子树是不是和右子树对称,返回bool
        # 其实每次就是判断传入的left和right值是不是相等,递归中不断传入需要接下来判断的左右值

        # 1 左空右空
        if left is None and right is None:
            return True
        # 2 左空右不空
        elif left is None and right is not None:
            return False
        # 3 左不空右空
        elif left is not None and right is None:
            return False
        # 4 左不空右不空
        # 4.1 左 != 右
        elif left.val != right.val:
            return False

        # 4.2 左 == 右
        # (left.val == right.val) 当前是true,继续递归
        outside = self.compare(left.left, right.right)
        inside = self.compare(left.right, right.left)

        return outside and inside

二叉树的最大深度

104. Maximum Depth of Binary Tree

class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        # 左右中
        left = self.maxDepth(root.left)
        right = self.maxDepth(root.right)
        return 1 + max(left, right)

 二叉树的最小深度

 根节点到最近的叶子节点的距离

111. Minimum Depth of Binary Tree

class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        # 左右中
        left = self.minDepth(root.left)
        right = self.minDepth(root.right)

        # 为了避免一种情况---root的左子树为空时,该边不算做depth的考虑范围
        if root.left is None and root.right != None:
            return 1 + right
        
        if root.right is None and root.left != None:
            return 1 + left
        
        return 1 + min(left, right)

 完全二叉树

左子树节点数量 + 右子树节点数量 + 1---------适用于任何一个BST

222. Count Complete Tree Nodes

class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        return self.countNodes(root.left) + self.countNodes(root.right) + 1

平衡二叉树

def maxDepth------左右中的遍历顺序,在递归中不断得到子树的高度,并判断每一个当前root的左右子树差是不是符合标准

信息是由left和right反馈给root

只要当前某一个root不符合了,就给标记一个-1,这个root可能是前一次递归的某个左子树或右子树,所以在递归中只要left/right的值碰到了-1,向根节点也反馈的是-1的信息

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if root is None:
            return True
        if self.maxDepth(root) == -1:
            return False
        return True
        
    def maxDepth(self, root):
        
        if root is None:
            return 0
        left = self.maxDepth(root.left)
        if left == -1:
            return -1
        right = self.maxDepth(root.right)
        if right == -1:
            return -1
      
        # 当发现任何一个当前节点的左右子树高度差超过1的时候,该树已经不可能符合了
        if abs(left - right) > 1:
            return -1
        else:
            return max(left, right) + 1

173. Binary Search Tree Iterator

全局变量---在init中命名,可以整个class调用的

class BSTIterator:

    def __init__(self, root: Optional[TreeNode]):
        
        # inorder---左中右
        arr = self.inorder(root)
        print(arr)
        

    def inorder(self, root):
        if not root:
            return []
        return self.inorder(root.left) + [root.val] + self.inorder(root.right)
        

    def next(self) -> int:
        

    def hasNext(self) -> bool:
        


# Your BSTIterator object will be instantiated and called as such:
# obj = BSTIterator(root)
# param_1 = obj.next()
# param_2 = obj.hasNext()

 tree的回溯

257. Binary Tree Paths

回溯: 先收集1,2,5;弹出2,5加入3

弹出2,5的过程就是回溯

回溯中使用全局变量---其他def可以调用并且随着不断递归执行def,该变量一直在更新

self.res.append(self.path[:]) ------coy path,收集路径的时候self.path[:]可以让path的变化不影响res

.join()的使用: ‘->'.join(list) # 将list中的所有元素用->相连接,此处的list应为str数组

map(str, path): 将int型数组转化为str数组、

class Solution:
    def __init__(self):
        self.path = []
        self.res = []

    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        if root is None:
            return []
        self.traversal(root)
        return self.res
       

    def traversal(self, cur):
        # 前序--中左右
        self.path.append(cur.val)

        # 递归的终止条件---遍历到leaf
        if cur.left is None and cur.right is None:
            new_path = "->".join(map(str, self.path[:]))
            self.res.append(new_path) # 收集该条路径
            return
        if cur.left:
            self.traversal(cur.left)
            self.path.pop()
        if cur.right:
            self.traversal(cur.right)
            self.path.pop()

左子树叶子合

404. Sum of Left Leaves

class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        # 对于每一个root----结果为root.left的ans和root.right的ans----由左右子树的结果得到root的结果----左右中
        if root is None:
            return 0
        if root.left is None and root.right is None:
            return 0

        left = self.sumOfLeftLeaves(root.left)  # 左
        
        if root.left and root.left.left is None and root.left.right is None:
            left = root.left.val
        right = self.sumOfLeftLeaves(root.right)  # 右
        ans = left + right # 中
        
        return ans

654. Maximum Binary Tree

 思路:确定root---确定root.left----确定root.right

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums) == 1:
            return TreeNode(nums[0])
        root = TreeNode(max(nums))
        max_index = nums.index(max(nums))

        left = nums[:max_index]
        
        if len(left) != 0:
            root.left = self.constructMaximumBinaryTree(left)
        
        right = nums[max_index+1:]
        if len(right) != 0:
            root.right = self.constructMaximumBinaryTree(right)
        return root

合并二叉树

617. Merge Two Binary Trees

class Solution:
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        # root1 root2都不空----直接相加
        # root1空
        # root2空
        
        if not root1: # 如果root1空
            return root2
        if not root2:
            return root1

        root = TreeNode(root1.val + root2.val)    
        root.left = self.mergeTrees(root1.left, root2.left)
        root.right = self.mergeTrees(root1.right, root2.right)
        return root

BST

700. Search in a Binary Search Tree

搜索思路:val比root大就向右搜索,小就向左搜索

终止条件就是:要么找到val了就停,要么遍历完还是没找到也停

返回值---当前的节点,treenode

class Solution:
    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        # 递归终止条件:
        if root is None:
            return root

        if root.val == val:
            return root
        
        if root.val > val:
            # 向左遍历
            cur = self.searchBST(root.left, val)
        if root.val < val:
            cur = self.searchBST(root.right, val)
        return cur

98. Validate Binary Search Tree

方法一:先写成inorder的数组形式,判断数组是不是单调递增

方法二:直接inorder遍历判断-----左中右

所谓的中就是对当前节点进行操作---本题中就是判断每次的val是不是递增的

递归返回值是bool

530. Minimum Absolute Difference in BST

class Solution:
    def __init__(self):
        self.res = float('inf')
        self.pre = None # pre记录上一次的cur
        # 如果不用全局变量,每次执行def traversal,pre都被初始化为null, 记录不了上一次的cur

    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        self.traversal(root)
        return self.res

    def traversal(self, cur):
      
        if cur is None:
            return 
        
        self.traversal(cur.left)
        if self.pre is not None:
            self.res = min(self.res, abs(cur.val - self.pre.val))
        self.pre = cur
        self.traversal(cur.right)

501. Find Mode in Binary Search Tree

class Solution:
    def __init__(self):
        self.res = {}
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        ans = []
        self.traversal(root)
        max_count = max(self.res.values())
        for j,i in self.res.items():
            if i == max_count:
                ans.append(j)
        return ans
        
    def traversal(self, cur):
        if cur is None:
            return 
        self.traversal(cur.left)
        if  cur.val in self.res.keys():
            self.res[cur.val] += 1
        else:
            self.res[cur.val] = 1
        self.traversal(cur.right)

701. Insert into a Binary Search Tree

class Solution:
    def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:          
        # 最底层---找到目标
        if root is None:
            node = TreeNode(val)
            return node
      
        if root.val < val:
            root.right = self.insertIntoBST(root.right, val)
        if root.val > val:
            root.left = self.insertIntoBST(root.left, val)
        return root

450. Delete Node in a BST

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:

        # 1. 没找到
        # 2. 没有左右child,直接delete
        # 3. 左右都有child,右替换,左连接到右边根节点的左孩子上,返回右root
        # 4. 左有,右没有,和左替换,返回左root
        # 5. 右有,左没有,和右替换,返回右root

        if root is None:
            return root
        
        # 底层找到目标
        if root.val == key:
            if root.left is None and root.right is None:
                return None
            elif root.left is None and root.right is not None:
                return root.right
            elif root.left is not None and root.right is None:
                return root.left
            else:
                cur = root.right
                while cur.left is not None:
                    cur = cur.left
                cur.left = root.left
                return root.right
        
        if root.val > key:
            root.left = self.deleteNode(root.left, key)
        if root.val < key:
            root.right = self.deleteNode(root.right, key)
        
        return root

669. Trim a Binary Search Tree

公共祖先

236. Lowest Common Ancestor of a Binary Tree

思路: 从底层向上遍历-----回溯-----左右中方便回溯

代码思路:对于某一个节点root来说,root.left 和root.right都

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root is None:
            return root
        if root is p or root is q:
            return root
        
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)

        if left and right:
            return root
        if left is None and right is not None:
            return right
        if right is None and left is not None:
            return left

235. Lowest Common Ancestor of a Binary Search Tree

递归函数有返回值:

遍历单支----判断递归函数返回的不为空就直接return

遍历整支----left = , right = , left和right的逻辑判断

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        # 从上到下的遍历
        if root == None:
            return root
        
        # 遍历左支
        if root.val > q.val and root.val > p.val:
            left = self.lowestCommonAncestor(root.left, p, q)
            if left is not None:
                return left

        # 遍历右支
        if root.val < q.val and root.val < p.val:
            right = self.lowestCommonAncestor(root.right, p, q)
            if right is not None:
                return right
        
        # 最底层的返回---找到目标
        return root

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值