返回

突破LeetCode289场周赛,程序猿冲鸭!

后端

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场周赛的四道题目的题解。希望大家能够从中有所收获,并不断提升自己的算法能力。