Datawhale组队学习笔记task2——leetcode面试题

文章目录

写在前面

教程内容来自Datawhale

开源教程:https://github.com/datawhalechina/leetcode-notes/blob/main/docs/ch07/index.md

在线学习网站:https://www.datawhale.cn/learn/summary/67

ε=(´ο`*)))唉感觉自己是个笨小孩儿,还在

Day5题目

1.0112.路径总和

解答

思路:DFS深度优先搜索遍历,一直向下找到叶子节点(需要同时判断节点的左右子树同时为空),如果到叶子节点时sum==0,说明找到了一条符合要求的路径。

python 复制代码
# Definition for a binary tree node.
# 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 not root:return False
        if not root.left and not root.right:
            return targetSum == root.val
        return self.hasPathSum(root.left,targetSum - root.val) or self.hasPathSum(root.right,targetSum - root.val)

时间复杂度:O(n)

空间复杂度:O(1)

题解:

回溯:利用DFS找到从根节点到叶子节点的所有路径,只要有任何一条路径的和等于sum,就返回true。

(并非严格意义上的回溯法,因为没有重复利用path变量)

python 复制代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def hasPathSum(self, root, sum):
        if not root: return False
        res = []
        return self.dfs(root, sum, res, [root.val])
        
    def dfs(self, root, target, res, path):
        if not root: return False
        if sum(path) == target and not root.left and not root.right:
            return True
        left_flag, right_flag = False, False
        if root.left:
            left_flag = self.dfs(root.left, target, res, path + [root.left.val])
        if root.right:
            right_flag = self.dfs(root.right, target, res, path + [root.right.val])
        return left_flag or right_flag

时间复杂度:O(n)

空间复杂度:O(1)

BFS:使用队列保存遍历到每个节点时的路径和,如果该节点恰好是叶子节点,并且路径和正好等于sum,说明找到了解。

python 复制代码
# Definition for a binary tree node.
# 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 not root:
            return False
        que = collections.deque()
        que.append((root,root.val))
        while que:
            node,path = que.popleft()
            if not node.left and not node.right and path == targetSum:
                return True
            if node.left:
                que.append((node.left,path + node.left.val))
            if node.right:
                que.append((node.right,path + node.right.val))
        return False

时间复杂度:O(n)

空间复杂度:O(n)

2.0113路径总和II

解答

题解:

典型的回溯问题,解法包含先序遍历+路径记录两部分:

  • 先序遍历:按照"根、左、右"的顺序,遍历树的所有节点。
  • 路径记录:在先序遍历中,记录从根节点到当前节点的路径。当路径满足 (1) 根节点到叶节点形成的路径 且 (2) 各节点值的和等于目标值 targetSum 时,将此路径加入结果列表。

    算法流程:
    函数pathSum(root,targetSum):
    初始化:结果列表res,路径列表path
    返回值:返回res即可
    函数recur(root,tar):
    递推参数:当前节点root,当前目标值tar。
    终止条件:若节点root为空,则直接返回
    递推工作:
    1.路径更新:将当前节点值root.val加入路径path
    2.目标值更新:tar = tar - root.val(即目标值tar从targetSum减至0)
    3.路径记录:当(1)root为叶节点且(2)路径和等于目标值,则将此路径path加入res
    4.先序遍历:递归左/右子节点
    5.路径恢复:向上回溯前,需要将当前节点从路径path中删除,即执行path.pop()
python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        res,path = [],[]
        def recur(root,tar):
            if not root:return
            path.append(root.val)
            tar -= root.val
            if tar == 0 and not root.left and not root.right:
                res.append(list(path))
            recur(root.left,tar)
            recur(root.right,tar)
            path.pop()

        recur(root,targetSum)
        return res

时间复杂度:O(n)

空间复杂度:O(n)

3.0101.对称二叉树

解答

题解:

对称二叉树定义: 对于树中 任意两个对称节点 L 和 R ,一定有:

L.val = R.val :即此两对称节点值相等。

L.left.val = R.right.val :即 L 的 左子节点 和 R 的 右子节点 对称。

L.right.val = R.left.val :即 L 的 右子节点 和 R 的 左子节点 对称。

根据以上规律,考虑从顶至低递归,判断每对左右节点是否对称,从而判断树是否为对称二叉树。

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        def recur(L,R):
            if not L and not R:return True
            if not L or not R or L.val != R.val:return False
            return recur(L.left,R.right) and recur(L.right,R.left)
        return not root or recur(root.left,root.right)

时间复杂度:O(N)

空间复杂度:O(N)

Day6题目

1.0124.二叉树中的最大路径和

解答

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxPathSum(self, root: Optional[TreeNode]) -> int:
        ans = -inf
        def dfs(node:Optional[TreeNode]) -> int:
            if node is None:
                return 0 #没有节点,和为0
            l_val = dfs(node.left) #左子树最大链和
            r_val = dfs(node.right) #右子树最大链和
            nonlocal ans
            ans = max(ans,l_val + r_val + node.val) #两条链拼成路径
            return max(max(l_val,r_val) + node.val,0) #当前子树最大链和(注意这里和0取最大值)
        dfs(root)
        return ans

时间复杂度:O(n)

空间复杂度:O(n)

2.0199.二叉树的右视图

解答

思考:即找每一层最右边的节点,可以利用层次遍历。

流程:

1、初始化队列,先将二叉树的根结点放入队列;根据队列是否为空作为循环条件;

2、获取当前层的元素个数(队列长度),并将队列尾部的元素值添加到右视图中。

3、按照队列长度遍历队列中的元素,并将其左右孩子(如果存在)添加到队列尾部,然后将当前元素出队。

4、重复步骤2,3,直到队列为空。

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if not root:return []
        q = deque([root])
        ans = []
        while q:
            nxt = deque()
            size = len(q)
            ans.append(q[-1].val)
            for _ in range(size):
                cur = q.popleft()
                if cur.left:
                    nxt.append(cur.left)
                if cur.right:
                    nxt.append(cur.right)
            q = nxt
        return ans

时间复杂度:O(n)

空间复杂度:O(n)

3.0226.翻转二叉树

解答

思考:递归

根据二叉树镜像的定义,考虑递归遍历(dfs)二叉树,交换每个节点的左 / 右子节点,即可生成二叉树的镜像。

python 复制代码
# Definition for a binary tree node.
# 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 not root:return
        tmp = root.left
        root.left = self.invertTree(root.right)
        root.right = self.invertTree(tmp)
        return root

时间复杂度 O(N) : 其中 N 为二叉树的节点数量,建立二叉树镜像需要遍历树的所有节点,占用 O(N) 时间。

空间复杂度 O(N) : 最差情况下(当二叉树退化为链表),递归时系统需使用 O(N) 大小的栈空间。

Day7题目

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

解答

2.0098.验证二叉搜索树

解答

3.0110.平衡二叉树

解答

Day8题目

1.0200.岛屿数量

解答

2.0695.导语的最大面积

解答

3.0129.求根节点到叶节点数字之和

解答

相关推荐
tingshuo291711 小时前
D006 【模板】并查集
笔记
tingshuo29171 天前
S001 【模板】从前缀函数到KMP应用 字符串匹配 字符串周期
笔记
西岸行者7 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
琢磨先生David7 天前
Day1:基础入门·两数之和(LeetCode 1)
数据结构·算法·leetcode
starlaky7 天前
Django入门笔记
笔记·django
勇气要爆发7 天前
吴恩达《LangChain LLM 应用开发精读笔记》1-Introduction_介绍
笔记·langchain·吴恩达
悠哉悠哉愿意7 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
超级大福宝7 天前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode
勇气要爆发7 天前
吴恩达《LangChain LLM 应用开发精读笔记》2-Models, Prompts and Parsers 模型、提示和解析器
android·笔记·langchain
Charlie_lll7 天前
力扣解题-88. 合并两个有序数组
后端·算法·leetcode