LeetCode周赛回顾:挑战图论压轴,难度不小
2023-11-21 13:51:51
LeetCode 周赛回顾:图论压轴题难倒众人,难度不小
上周末的 LeetCode 周赛难度不小,超出以往水平,令人大开眼界。本次周赛由理想汽车赞助,大奖只是理想汽车的周边,与豪气公司送 iWatch 的手笔相比,略显小气。
赛题回顾
本次周赛题目涵盖图论、字符串处理、动态规划等领域,其中图论压轴题更是难倒了众多参赛者。
第一题:检查每一行每一列都包含所有整数
这道题考察基础数组操作和集合应用。给定二维数组 grid
,要求判断每一行和每一列是否都包含所有整数 [1, n]
。
解法:使用两个集合分别存储每一行和每一列的整数,遍历数组,将整数添加到对应集合。最后检查集合是否包含所有整数。
def checkValid(grid: List[List[int]]) -> bool:
rows = len(grid)
cols = len(grid[0])
for i in range(rows):
row_set = set()
for j in range(cols):
row_set.add(grid[i][j])
if len(row_set) != rows:
return False
for j in range(cols):
col_set = set()
for i in range(rows):
col_set.add(grid[i][j])
if len(col_set) != cols:
return False
return True
第二题:找到字符串中指定单词的最短距离
这道题考察字符串处理中的滑动窗口算法。给定字符串 s
和单词 word
,要求找到 word
在 s
中出现的所有位置,并返回这些位置之间的最短距离。
解法:使用两个指针 left
和 right
定义滑动窗口。移动指针,直到窗口包含 word
。计算窗口长度,并与当前最短距离比较,更新最短距离。
def shortestDistance(s: str, word: str) -> int:
left = 0
right = 0
min_distance = float('inf')
word_len = len(word)
while right < len(s):
if s[right:right+word_len] == word:
min_distance = min(min_distance, right - left + 1)
left = right + 1
right += 1
return min_distance if min_distance != float('inf') else -1
第三题:删除石子使得石子堆不超过最大值
这道题考察动态规划中的背包问题。给定一堆石子,每个石子有一个重量。要求从石子堆中取出一些石子,使得剩下的石子堆重量不超过给定最大值。
解法:定义状态 dp[i][j]
,表示前 i
个石子中,取出的石子重量恰好为 j
的所有取法。使用递推关系计算 dp[i][j]
。找到最小的 j
,使得 dp[n][j]
不为 0。
def minStoneSum(piles: List[int], max_weight: int) -> int:
n = len(piles)
dp = [[0] * (max_weight + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, max_weight + 1):
dp[i][j] = dp[i - 1][j]
if piles[i - 1] <= j:
dp[i][j] = max(dp[i][j], dp[i - 1][j - piles[i - 1]] + piles[i - 1])
return dp[n][max_weight]
第四题:检查是否每一棵树都是另一个树的子树
这道题是本次周赛的压轴题,考察图论中的子树问题。给定两棵二叉树 root
和 subRoot
,要求判断 subRoot
是否为 root
的子树。
解法:递归比较 root
和 subRoot
的根节点。如果根节点相等,递归比较 root
和 subRoot
的左子树和右子树。如果在递归过程中,发现 subRoot
的某个子树与 root
的某个子树不相等,则 subRoot
不是 root
的子树。
def isSubtree(root: TreeNode, subRoot: TreeNode) -> bool:
if not root:
return False
if not subRoot:
return True
if root.val == subRoot.val:
if isSameTree(root, subRoot):
return True
return isSubtree(root.left, subRoot) or isSubtree(root.right, subRoot)
def isSameTree(root1: TreeNode, root2: TreeNode) -> bool:
if not root1 and not root2:
return True
if not root1 or not root2:
return False
if root1.val != root2.val:
return False
return isSameTree(root1.left, root2.left) and isSameTree(root1.right, root2.right)
结论
本次 LeetCode 周赛的题目难度不小,图论压轴题更是难倒了众多参赛者。但是,通过认真分析题目,掌握算法知识,我们还是能够顺利解题的。希望大家能够通过本次周赛,对算法竞赛有更深入的了解,并不断提高自己的算法水平。
常见问题解答
-
本次周赛的难度如何?
本次周赛的难度不小,特别是第四题图论压轴题,难倒了众多参赛者。 -
周赛题目覆盖了哪些算法领域?
本次周赛题目涵盖了图论、字符串处理、动态规划等多个领域。 -
如何提高算法竞赛水平?
可以通过认真分析题目,掌握算法知识,并多加练习来提高算法竞赛水平。 -
第四题的解法是否还有其他方法?
第四题可以使用遍历root
中所有子树,并与subRoot
进行比较的方法解决,但这会比较低效。 -
如何判断两棵二叉树是否相同?
可以通过递归比较两棵二叉树的根节点、左子树和右子树是否相等来判断两棵二叉树是否相同。