小白的深度优先搜索(Depth First Search)学习日记(Python)

1.二叉平衡树

二叉平衡树是指该树的所有节点的左右子树的深度相差不超过1.

题目:力扣110.平衡二叉树

思路1:使用DFS对二叉树进行后序遍历,将每个节点的左右子树的深度求出来,然后判断该节点的左右子树深度是否不超过1,将结果添加到全局变量isBalance中。最后对isBalance进行遍历,如果存在False,则该二叉树不是平衡二叉树,否则是平衡二叉树。

代码:

点击查看代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        isBalance = []
        def dfs(root:Optional[TreeNode]):
            if root is None:
                return 0
            left_nums = dfs(root.left)
            right_nums = dfs(root.right)
            if fabs(left_nums-right_nums)<=1:
                isBalance.append(True)
            else:
                isBalance.append(False)
            return max(left_nums,right_nums)+1
        dfs(root)
        if isBalance == []:
            return True
        for i in range(0,len(isBalance)):
            if isBalance[i]==False:
                return False
        return True
时间复杂度:由于要对二叉树的每个节点都要遍历一次,所以时间复杂度是O(n)

空间复杂度:由于实现声明一个全局变量存放每个节点是否满足左右子树深度相差不超过1,所以空间复杂度也为O(n)。
2.二叉树的最小深度

题目:力扣111.二叉树的最小深度

最小深度是指从根节点到最近叶子节点的最短路径上的节点数量。

思路:求出每一个节点的最小深度,对于一个节点,如果它有左右子树,则该节点的最小深度是左右子树最小深度+1;如果该节点没有左子树或者没有右子树,则该节点的最小深度就是该节点的深度;如果该节点没有孩子,则同样,该节点的最小深度就是该节点的深度。综上所述,对该二叉树进行后序遍历,判断每一个节点的最小深度,最后返回二叉树的最小深度。

代码:

点击查看代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        def dfs(root:Optional[TreeNode]):
            if root is None:
                return 0
            left_depth = dfs(root.left)
            right_depth = dfs(root.right)
            if right_depth==0 or left_depth==0:
                return max(left_depth,right_depth)+1
            else:
                return min(left_depth,right_depth)+1
        return dfs(root)

时间复杂度:O(n)

空间复杂度:O(n)
3.路径总和

题目:力扣112.路径总和

思路:使用前序遍历每一个节点,求出从根节点到每个叶子节点的路径权值之和,然后从这些路径和中寻找是否与目标一致的。

代码:

点击查看代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if root is None:
            return False
        path_value = []
        def dfs(root:Optional[TreeNode],target_value):
            if root is None:
                return 
            target_value+=root.val
            ###判断该点是否是叶子节点
            if root.left is None and root.right is None:
                path_value.append(target_value)
                return
            dfs(root.left,target_value)
            dfs(root.right,target_value)
        value=0
        dfs(root,value)
        for i in range(0,len(path_value)):
            if path_value[i]==targetSum:
                return True
        return False

时间复杂度:O(n)
空间复杂度:O(n)
4.二叉树的前序遍历

代码:

点击查看代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        nodes_val = []
        def dfs(root:Optional[TreeNode]):
            if root is None:
                return 
            nodes_val.append(root.val)
            dfs(root.left)
            dfs(root.right)
        dfs(root)
        return nodes_val

5.二叉树的后序遍历

代码:

点击查看代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        nodes_val = []
        def dfs(root:Optional[TreeNode]):
            if root is None:
                return 
            dfs(root.left)
            dfs(root.right)
            nodes_val.append(root.val)
        dfs(root)
        return nodes_val

6.翻转二叉树

思路:翻转二叉树,对于每一个节点都要对其左右子树进行翻转。这里体现的一个思想就是自底向顶,从叶子节点开始,逐步往上,依次翻转,所以采用后序遍历,先递到叶子节点,之后逐步归,进行翻转。

代码:

点击查看代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return None
        def dfs(root:Optional[TreeNode]):
            if root is None:
                return 
            dfs(root.left)
            dfs(root.right)
            new_Node = root.left
            root.left = root.right
            root.right = new_Node
        dfs(root)
        return root
7.二叉树的所有路径

思路:前序遍历二叉树,对于遍历到的每一个节点加入到当前路径中,直到叶子节点,得到一条完整路径,将其加入到列表中,直到得到所有路径。

代码:

点击查看代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        path = []
        def dfs(root:Optional[TreeNode],path_str):
            if root is None:
                return 
            path_str += str(root.val) + "->"
            ###如果该点是叶子节点,直接返回
            if root.left is None and root.right is None:
                path.append(path_str[:-2])
                return
            dfs(root.left,path_str)
            dfs(root.right,path_str)
        path_str=''
        dfs(root,path_str)
        return path
posted @ 2024-04-09 21:43  busakura  阅读(57)  评论(0)    收藏  举报