【LeetCode】力扣刷题之路
题目(20240226~20240301)
104.二叉树的最大深度
给定一个二叉树 root ,返回其最大深度。
二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:3
示例 2:
输入:root = [1,null,2]
输出:2
提示:
树中节点的数量在 [0, 10^4] 区间内。
-100 <= Node.val <= 100
知识点回顾
深度优先搜索 (DFS):深度优先搜索算法,是一种在开发爬虫早期使用较多的方法。它的目的是要达到被搜索结构的叶结点 (即那些不包含任何超链的HTML文件) 。
宽度优先搜索 (BFS): 又称广度优先搜索,是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。
代码
方法1:深度优先搜索 (Depth-First-Search)
from typing import Optional, List
# 定义二叉树节点
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# 递归
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
# 空树
if not root:
return 0
else:
left_depth = self.maxDepth(root.left)
right_depth = self.maxDepth(root.right)
max_depth = max(left_depth, right_depth)
return max_depth + 1
if __name__ == "__main__":
# 构造测试二叉树的最大深度 示例1
root = TreeNode(3)
root.left = TreeNode(9)
root.right = TreeNode(20)
root.right.left = TreeNode(15)
root.right.right = TreeNode(7) # 输入:[3,9,20,null,null,15,7]
# 测试递归最大深度
s = Solution()
res = s.maxDepth(root)
print(res) # 输出:3
# 示例2
r2 = TreeNode(1)
r2.right = TreeNode(2) # 输入:root = [1,null,2]
res2 = s.maxDepth(r2)
print(res2) # 输出:2
方法2:宽度优先搜索 (Breadth-First-Search)
from typing import Optional, List
# 定义二叉树节点
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# 迭代
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> List[int]:
if not root: # 空树
return 0
depth = 0
root_list = [root] # 转化为列表
while root_list:
for i in range(len(root_list)):
n = root_list.pop(0) # 弹出根节点
if n.left:
root_list.append(n.left) # 左子树
if n.right:
root_list.append(n.right) # 右子树
depth += 1
return depth
if __name__ == "__main__":
# 构造测试二叉树的最大深度 示例1
root = TreeNode(3)
root.left = TreeNode(9)
root.right = TreeNode(20)
root.right.left = TreeNode(15)
root.right.right = TreeNode(7) # 输入:[3,9,20,null,null,15,7]
# 测试迭代最大深度
s = Solution()
res = s.maxDepth(root)
print(res) # 输出:3
# 示例2
r2 = TreeNode(1)
r2.right = TreeNode(2) # 输入:root = [1,null,2]
res2 = s.maxDepth(r2)
print(res2) # 输出:2
122. 买卖股票的最佳时机 II
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候最多只能持有一股股票。你也可以先购买,然后在同一天出售。
返回 你能获得的最大利润 。
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
总利润为 4 。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。
提示:
1 <= prices.length <= 3 * 10^4
0 <= prices[i] <= 10^4
知识点回顾
动态规划:简称DP算法,英文全称Dynamic Programming,是运筹学的一个分支,是求解决策过程最优化的过程。一般求解最值(最优、最大、最小、最长)问题。在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。因此各个阶段决策的选取不能任意确定,它依赖于当前面临的状态,又影响以后的发展。当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线。这种把一个问题看作是一个前后关联具有链状结构的多阶段过程就称为多阶段决策过程,这种问题称为多阶段决策问题。在多阶段决策问题中,各个阶段采取的决策,一般来说是与时间有关的,决策依赖于当前状态,又随即引起状态的转移,一个决策序列就是在变化的状态中产生出来的,故有“动态”的含义,称这种解决多阶段决策最优化的过程为动态规划方法。
贪心算法: 又称贪婪算法,是指在对问题求解时,总是做出在当前看来是最好的选择。基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一 步都要确保能获得局部最优解。
代码
方法1:DP算法 (Dynamic Programming)
from typing import List
# DP算法
class Solution:
def maxProfit(self, prices: List[int]) -> int:
df = [[0] * 2 for _ in range(len(prices))] # 构造DataFrame数据结构 [[0, 0],...]
# df[i][0]表示第i天不持有股票(未买/卖出), df[i][1]表示第i天持有股票(未卖/买入)
df[0][0], df[0][1] = 0, - prices[0] # 定义第 0 天不持有利润为0,第 0 天持有利润则为 -prices[0],df:[[0, -prices[0]],...]
i = 0
profit = 0
for i in range(len(prices) - 1):
df[i + 1][0] = max(df[i][0], df[i][1] + prices[i + 1]) # T+1 天卖出获取的最大利润
df[i + 1][1] = max(df[i][1], df[i][0] - prices[i + 1]) # T+1 天买入获取的最大利润
i += 1
profit = df[i][0] # 第i天卖出后获取最大利润
return profit
if __name__ == "__main__":
# 买卖股票的最佳时机 II 示例1
prices = [7, 1, 5, 3, 6, 4]
s = Solution()
res = s.maxProfit(prices)
print(res) # 输出:7
# 示例2
p2 = [1, 2, 3, 4, 5]
r2 = s.maxProfit(p2)
print(r2) # 输出:4
# 示例3
p3 = [7, 6, 4, 3, 1]
r3 = s.maxProfit(p3)
print(r3) # 输出:0
方法2:贪心算法 (Greedy Algorithm)
from typing import List
# 贪心算法
class Solution:
def maxProfit(self, prices: List[int]) -> int:
profit = 0
for i in range(len(prices) - 1):
if prices[i] < prices[i + 1]: # 盈利可计
profit += prices[i + 1] - prices[i] # T 日买进 T+1 日卖出 可获取的利润累加
return profit
if __name__ == "__main__":
# 买卖股票的最佳时机 II 示例1
prices = [7, 1, 5, 3, 6, 4]
s = Solution()
res = s.maxProfit(prices)
print(res) # 输出:7
# 示例2
p2 = [1, 2, 3, 4, 5]
r2 = s.maxProfit(p2)
print(r2) # 输出:4
# 示例3
p3 = [7, 6, 4, 3, 1]
r3 = s.maxProfit(p3)
print(r3) # 输出:0