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.求根节点到叶节点数字之和

解答

相关推荐
艾莉丝努力练剑2 小时前
【AI接入大模型SDK】ChatSDK示例验证
人工智能·学习·面试·大模型·sdk
葡萄成熟时 !7 小时前
JAVA 常用API学习笔记
java·笔记·学习
DevOpenClub7 小时前
个人公开市场研究笔记功能需求文档
笔记
鹿角片ljp8 小时前
LeetCode 46. 全排列|吃透回溯
算法·leetcode·职场和发展
别动我齐刘海9 小时前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
.道阻且长.10 小时前
11.LeetCode算法习题讲解--滑动窗口--将x减到0的最小操作数
算法·leetcode·职场和发展
wenyq711 小时前
LeetCode 2460. Apply Operations to an Array
算法·leetcode
05664611 小时前
agent学习——流式响应与文本切分
网络·python·学习
青 春 记 忆11 小时前
LeetCode 142. 环形链表 II|Python 解法详解
python·leetcode·链表
for_ever_love__12 小时前
python基础语法学习: 面向对象的三大特性
开发语言·python·学习