返回

LeetCode13:机器人运动范围,行走四方的策略!

IOS

前言

在广阔的计算机科学领域中,算法扮演着至关重要的角色。算法是一种求解特定问题的明确指令集,它指导计算机一步步地执行操作,最终得到我们想要的结果。在算法的世界里,动态规划和回溯法是两大经典且实用的算法范式。

动态规划

动态规划是一种自底向上的求解方法,它将复杂问题分解成一系列子问题,并通过逐步求解子问题来得到最终解。动态规划的精髓在于「记忆化」,即在求解过程中记录子问题的解,避免重复计算。

回溯法

回溯法是一种自顶向下的求解方法,它通过穷举所有可能的解法,逐步探索搜索空间。当发现某条路径不可行时,回溯法会回退到上一步,尝试其他路径。回溯法的优势在于它的系统性和完备性,可以保证找到所有可能的解。

题目解析

现在,让我们把目光投向「剑指 Offer 13. 机器人的运动范围」这道题目。题目中给定了一个 m 行 n 列的方格,机器人从 (0, 0) 出发,可以向上下左右四个方向移动。机器人的运动范围由其「各位数字之和」决定,即机器人只能移动到各位数字之和不超过给定阈值 threshold 的方格中。我们的目标是求解机器人可以到达的方格数量。

动态规划解法

对于这道题目,动态规划是一种非常适合的解法。我们可以定义一个二维数组 dp,其中 dp[i][j] 表示机器人从 (0, 0) 出发,移动到 (i, j) 方格的运动范围。根据题意,我们可以得到以下递推公式:

dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + (check(i, j) ? 1 : 0)

其中,check(i, j) 函数用于判断机器人是否可以移动到 (i, j) 方格。如果可以移动,则返回 true,否则返回 false。

回溯法解法

回溯法也是一种可行的解法。我们可以从 (0, 0) 出发,逐个探索机器人可以移动的方格。当机器人移动到某个方格时,如果其运动范围超过了阈值,则回退到上一步,尝试其他路径。

代码实现

下面是两种解法的代码实现:

动态规划解法:

def movingCount(m: int, n: int, threshold: int) -> int:
    dp = [[0] * n for _ in range(m)]
    for i in range(m):
        for j in range(n):
            if i == 0 and j == 0:
                dp[i][j] = 1
            else:
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
                if check(i, j, threshold):
                    dp[i][j] += 1
    return dp[m - 1][n - 1]

def check(i: int, j: int, threshold: int) -> bool:
    sum = 0
    while i > 0 or j > 0:
        sum += i % 10 + j % 10
        i //= 10
        j //= 10
    return sum <= threshold

回溯法解法:

def movingCount(m: int, n: int, threshold: int) -> int:
    visited = set()
    return dfs(0, 0, m, n, threshold, visited)

def dfs(i: int, j: int, m: int, n: int, threshold: int, visited: set) -> int:
    if i < 0 or i >= m or j < 0 or j >= n or (i, j) in visited or not check(i, j, threshold):
        return 0
    visited.add((i, j))
    return 1 + dfs(i + 1, j, m, n, threshold, visited) + dfs(i - 1, j, m, n, threshold, visited) + \
           dfs(i, j + 1, m, n, threshold, visited) + dfs(i, j - 1, m, n, threshold, visited)

def check(i: int, j: int, threshold: int) -> bool:
    sum = 0
    while i > 0 or j > 0:
        sum += i % 10 + j % 10
        i //= 10
        j //= 10
    return sum <= threshold

总结

在本文中,我们深入探讨了「剑指 Offer 13. 机器人的运动范围」这道题目,并从动态规划和回溯法两个角度给出了详细的解法。动态规划的递推思想和回溯法的穷举探索,都展现了算法之美。通过对算法的理解和运用,我们不仅可以解决实际问题,更能领悟计算机科学的精髓。

延伸思考

  • 尝试优化动态规划解法的空间复杂度。
  • 探索其他求解这道题目的方法,例如广度优先搜索。
  • 将这道题目推广到三维或更高维度的空间中。