突破LeetCode289场周赛,程序猿冲鸭!
2023-12-24 23:19:56
LeetCode第289场周赛已落下帷幕,四道精彩纷呈的算法难题激发了众多程序员的热情。现在,让我们一起来回顾这四道难题的题解,领略算法之美。
第一题:可到达节点数的最大值
题目链接:https://leetcode.cn/problems/maximum-number-of-reachable-points-on-a-grid/
题意:给定一个二进制网格 grid,其中 0 表示障碍物,1 表示可以到达的单元格。您有一个机器人,它只能上下左右移动,并且不能穿越障碍物。求出从左上角(0, 0)开始,机器人能够到达的单元格的最大数量。
解析:
这道题考验了我们对图的搜索和遍历能力。我们可以使用广度优先搜索(BFS)算法来解决它。从左上角开始,将所有与之相邻的单元格入队,然后依次将队首元素出队,并将其相邻单元格入队。重复这一过程,直到队列为空。这样,我们就能够遍历到所有可以到达的单元格。
def max_reachable_points(grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
# Initialize a queue to store the cells to be visited
queue = collections.deque([(0, 0)])
# Set of visited cells
visited = set()
# Maximum number of reachable cells
max_reachable = 0
# BFS traversal
while queue:
# Pop the first cell from the queue
cell = queue.popleft()
x, y = cell
# If the cell is valid and not visited
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and (x, y) not in visited:
# Mark the cell as visited
visited.add((x, y))
# Increment the number of reachable cells
max_reachable += 1
# Add the adjacent cells to the queue
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
new_x = x + dx
new_y = y + dy
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]) and grid[new_x][new_y] == 1:
queue.append((new_x, new_y))
return max_reachable
第二题:字符串中第一个唯一的字符
题目链接:https://leetcode.cn/problems/first-unique-character-in-a-string/
题意:给定一个字符串 s,找到第一个不重复的字符,并返回其索引。如果不存在不重复的字符,则返回 -1。
解析:
这道题考验了我们对字符串的处理能力。我们可以使用哈希表来解决它。首先,我们将字符串中的每个字符及其出现次数存储在哈希表中。然后,我们遍历哈希表,找到第一个出现次数为 1 的字符,并返回其索引。如果不存在这样的字符,则返回 -1。
def first_unique_char(s):
"""
:type s: str
:rtype: int
"""
# Create a dictionary to store the character counts
char_counts = {}
# Iterate over the string and update the character counts
for char in s:
char_counts[char] = char_counts.get(char, 0) + 1
# Iterate over the string again and find the first character with a count of 1
for i, char in enumerate(s):
if char_counts[char] == 1:
return i
# Return -1 if no unique character is found
return -1
第三题:最大子数组和
题目链接:https://leetcode.cn/problems/maximum-subarray/
题意:给定一个整数数组 nums,找到连续子数组的最大和。
解析:
这道题考验了我们对动态规划的理解。我们可以使用动态规划来解决它。首先,我们将数组中的每个元素作为连续子数组的起始元素,并计算出以该元素为起始元素的连续子数组的最大和。然后,我们将这些最大和存储在一个数组中。最后,我们找到数组中的最大值,并返回它。
def max_subarray_sum(nums):
"""
:type nums: List[int]
:rtype: int
"""
# Create an array to store the maximum subarray sums
max_subarray_sums = [nums[0]]
# Iterate over the array and update the maximum subarray sums
for i in range(1, len(nums)):
max_subarray_sums.append(max(nums[i], max_subarray_sums[i - 1] + nums[i]))
# Return the maximum subarray sum
return max(max_subarray_sums)
第四题:二叉树的最小深度
题目链接:https://leetcode.cn/problems/minimum-depth-of-binary-tree/
题意:给定一个二叉树,找出其最小深度。二叉树的最小深度是根节点到最近叶节点的最短路径上的节点数。
解析:
这道题考验了我们对树的搜索和遍历能力。我们可以使用深度优先搜索(DFS)算法来解决它。从根节点开始,遍历整个二叉树,并记录下到达每个叶节点的最短路径。最后,我们找到所有最短路径中的最小值,并返回它。
def min_depth(root):
"""
:type root: TreeNode
:rtype: int
"""
# If the root is null, the depth is 0
if not root:
return 0
# If the root has no left and right children, the depth is 1
if not root.left and not root.right:
return 1
# If the root has only a left child, the depth is 1 + the minimum depth of the left subtree
if not root.right:
return 1 + min_depth(root.left)
# If the root has only a right child, the depth is 1 + the minimum depth of the right subtree
if not root.left:
return 1 + min_depth(root.right)
# If the root has both left and right children, the depth is 1 + the minimum depth of the shorter subtree
return 1 + min(min_depth(root.left), min_depth(root.right))
以上就是LeetCode第289场周赛的四道题目的题解。希望大家能够从中有所收获,并不断提升自己的算法能力。