【LeetCode】二叉树相关问题

DFS 遍历使用递归

def dfs(TreeNode root) {
    if (root == None) {
        return;
    }
    dfs(root.left)
    dfs(root.right)
}

BFS 遍历使用队列数据结构

def bfs(TreeNode root):
    queue = []
    queue.append(root)
    while len(queue) > 0
        node = queue.pop(); // Java 的 pop 写作 poll()
        if node.left: 
            queue.append(node.left)

        if node.right
            queue.append(node.right)

在这里插入图片描述

BFS 的应用一:层序遍历

LeetCode-102 给定一个二叉树,返回其按层序遍历得到的节点值。 层序遍历即逐层地、从左到右访问所有结点。

# 广度优先遍历
class Solution:
    def levelOrder(self, root):
        if not root:
            return []
        res = []
        queue = [root]
        while queue:
            length = len(queue)
            level = []
            for i in range(length):
                node = queue.pop(0)
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)

            res.append(level)
        return res

剑指 Offer 32 - I. 从上到下打印二叉树

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        res = [root]
        tmp = []
        while res:
            node = res.pop(0)
            tmp.append(node.val)
            if node.left:
                res.append(node.left)
            if node.right:
                res.append(node.right)
        return tmp
`
1 在这里插入代码片肯定会用到 deque 的结构用来模拟队列,BFS精髓也在这里。
2 队列里肯定是有一个初始点
3 然后每次处理从队列中出队一个元素
4 对元素进行扩张(具体如何扩张需要根据题目要求)
5 对于扩张后满足某条件的点再进行处理,根据需要进入队列,进入队列的点就是扩到下一层的点(不同题目需要处理的方法不同,大家灵活运用)
6 然后接着循环处理 deque 中的元素,直到 deque 为空,则代表所有点都已经完成扩张
7 最后根据题目要求输出结果(当然这已经不属于 BFS 模板的范围了)
8 所有 BFS 的模板题都大致是这个思路,只不过是可能有小的变形。`

LeetCode 102. 二叉树最大深度

DFS(深度优先搜索)

给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        left = self.maxDepth(root.left)
        right = self.maxDepth(root.right)
        return max(left,right) + 1 

LeetCode 110. 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root: return True
        if abs(self.depth(root.left) - self.depth(root.right)) > 1:
            return False
             
        return self.isBalanced(root.left) and self.isBalanced(root.right)

    def depth(self, root):
        if not root: return 0
        return max(self.depth(root.left), self.depth(root.right)) + 1

LeetCode 199.二叉树的右视图

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
【LeetCode】二叉树相关问题_第1张图片

# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        res = []
        queue = [root]
        while queue:
            length = len(queue)
            level = []
            for i in range(length):
                node = queue.pop(0)
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)

            res.append(level[-1])
        return res        

LeetCode 23. 合并K个排序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
【LeetCode】二叉树相关问题_第2张图片

# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def mergeKLists(self, lists):
        # 把节点值存入列表,然后排序,最后再返回节点
        if not lists or len(lists)==0:
            return []
        res = []
        for p in lists:
            while p:
                res.append(p.val)
                p = p.next
        
        if len(res) == 1:
            return ListNode(res[0])
        res.sort()
        root = ListNode(1)
        head = root
        for i in range(0,len(res)):
            node = ListNode(res[i])
            head.next = node
            head = head.next
        return root.next

LeetCode 124.二叉树中最大路径和

【LeetCode】二叉树相关问题_第3张图片

class Solution(object):
    def maxPathSum(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        self.__max = root.val
        self.dfs(root)
        return self.__max
    
    def dfs(self,root):
        if not root:
            return  None
        left = max(0,self.dfs(root.left))  # 如果小于零则不需要添加
        right = max(0,self.dfs(root.right))
        self.__max = max(self.__max,left+root.val+right)
        return max(left,right) + root.val

LeetCode 103. 二叉树的锯齿形层次遍历

【LeetCode】二叉树相关问题_第4张图片

class Solution(object):
    def zigzagLevelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return []
        res = []
        queue = [root]
        flag = True
        while queue:
            length = len(queue)
            level = []
            for i in range(length):
                node = queue.pop(0)
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            if flag:
                res.append(level)
                flag = False
            else:
                res.append(level[::-1])
                flag = True
            
        return res 

LeetCode 257. 二叉树的所有路径

【LeetCode】二叉树相关问题_第5张图片

    def hasPathSum(self, root, sumnum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: bool
        """
        # 路径和为某一个值
        # if not root:
        #     return False
        # if not root.left and not root.right:
        #     return sum == root.val
        # return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)
        
        if not root:
            return []
        res = []
        def dfs(root,res,path):
            if sum(path) == sumnum and not root.left and not root.right:
                res.append(path)
            if root.left:
                dfs(root.left,res,path+[root.left.val])
            if root.right:
                dfs(root.right,res,path+[root.right.val])
        dfs(root,res,[root.val])
		return res

LeetCode 101. 对称二叉树

【LeetCode】二叉树相关问题_第6张图片

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        def dfs(left,right):
            if not left and not right:   ##同时为空
                return True
            if not left or not right:    #一个值为空
                return False
            if left.val != right.val :  #左右两个值不相等
                return False  
            if left and right:
                return dfs(left.left,right.right) and dfs(left.right,right.left)
        
        return dfs(root.left,root.right)  # # 用递归函数,比较左节点,右节点
# 队列实现
class Solution(object):
	def isSymmetric(self, root):
		"""
		:type root: TreeNode
		:rtype: bool
		"""
		if not root or not (root.left or root.right):
			return True
		# 用队列保存节点	
		queue = [root.left,root.right]
		while queue:
			# 从队列中取出两个节点,再比较这两个节点
			left = queue.pop(0)
			right = queue.pop(0)
			# 如果两个节点都为空就继续循环,两者有一个为空就返回false
			if not (left or right):
				continue
			if not (left and right):
				return False
			if left.val!=right.val:
				return False
			# 将左节点的左孩子, 右节点的右孩子放入队列
			queue.append(left.left)
			queue.append(right.right)
			# 将左节点的右孩子,右节点的左孩子放入队列
			queue.append(left.right)
			queue.append(right.left)
		return True



LeetCode 106.从中序与后序遍历序列构造二叉树

【LeetCode】二叉树相关问题_第7张图片

class Solution(object):
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        if not inorder and not postorder:
            return None
        
        def helper(ino,pos):
            if not pos:
                return None
            root = TreeNode(pos[-1]) # 根节点
            
            index = ino.index(pos[-1])
            
            root.left = helper(ino[:index],pos[:index]) #中序左,后序左
            root.right = helper(ino[index+1:],pos[index:-1]) #中序右,后序右
            
            return root
        
        return helper(inorder,postorder)

LeetCode 107.从前序与中序遍历序列构造二叉树

【LeetCode】二叉树相关问题_第8张图片

class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        if not preorder and inorder:
            return None
        
        def helper(pre,ino):
            if not pre:
                return None
            root = TreeNode(pre[0])  #根节点
            
            index = ino.index(pre[0])  # 一分为2
            
            root.left = helper(pre[1:index+1],ino[:index])
            root.right = helper(pre[index+1:],ino[index+1:])
            
            return root
        
        return helper(preorder,inorder)

LeetCode 128. 最长连续序列

【LeetCode】二叉树相关问题_第9张图片

class Solution:
    def longestConsecutive(self, nums):
        longest_streak = 0
        num_set = set(nums)

        for num in num_set:
            if num - 1 not in num_set:  # 找到连续字段中的最小的,开始计数
                current_num = num
                current_streak = 1

                while current_num + 1 in num_set:
                    current_num += 1
                    current_streak += 1

                longest_streak = max(longest_streak, current_streak)

        return longest_streak

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

【LeetCode】二叉树相关问题_第10张图片

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if not root or root == p or root == q: return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if not left: return right
        if not right: return left
        return root

98. 验证二叉搜索树

【LeetCode】二叉树相关问题_第11张图片

当前节点的值是其左子树的值的上界(最大值)
当前节点的值是其右子树的值的下界(最小值)
class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """     
        def BFS(root, left, right):
            if root is None:
                return True
            
            if left < root.val < right:
                return BFS(root.left, left, root.val) and BFS(root.right, root.val, right)
            else:
                return False

        return BFS(root, -float('inf'), float('inf'))

LeetCode 53. 最大子序和

【LeetCode】二叉树相关问题_第12张图片

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i in range(1,len(nums)):
            nums[i] = nums[i] + max(nums[i-1],0)
        return max(nums)
class Solution(object):
    def maxSubArray(self, nums):
        """
        for i in range(1,len(nums)):
            nums[i] = nums[i] + max(nums[i-1],0)
        return max(nums)
        """
        maxnum = nums[0]
        sum = 0
        for i in nums:
            if sum > 0:
                sum += i
            else:
                sum = i
            maxnum = max(sum,maxnum)
        return maxnum

你可能感兴趣的:(刷题笔记,二叉树,队列,链表,算法,列表)