返回

力扣 241. 为运算表达式设计优先级:DFS + 记忆化搜索

后端

导言

在解决力扣 241 时,我们面临的挑战是设计一个算法,为一个包含运算符和操作数的给定表达式找到最大可能的计算结果。这种优先级问题要求我们灵活地处理各种运算符,例如加法、减法和乘法,以最大化表达式的值。

方法:DFS + 记忆化搜索

我们精心设计的解决方案巧妙地融合了深度优先搜索 (DFS) 和记忆化搜索。

1. DFS

DFS 算法从表达式的根节点开始,并沿着每个可能的分支进行递归遍历。在每个分支中,我们探索各种优先级组合,尝试对表达式应用不同的运算符顺序。

2. 记忆化搜索

为了优化 DFS 过程,我们引入记忆化搜索,使用 dp[i][j] 数组存储表达式从 i 到 j 位置的子表达式的最大值。通过存储中间结果,我们可以避免重复计算相同的子表达式,从而提高算法的效率。

算法步骤

  1. 初始化: 我们将给定的表达式处理成 ops 数组,其中每个元素为操作数或操作符。
  2. DFS 递归: 我们执行 DFS 递归,尝试在表达式中插入括号,并计算每个优先级组合下的最大值。
  3. 记忆化存储: 在 DFS 过程中,我们将子表达式的最大值存储在 dp[i][j] 数组中,以供后续使用。
  4. 返回最大值: 最后,我们返回表达式从头到尾的子表达式的最大值。

代码实现

def max_value(ops):
  n = len(ops)
  dp = [[-float('inf')] * (n + 1) for _ in range(n + 1)]

  def dfs(i, j):
    if i > j:
      return 0
    if i == j:
      return int(ops[i])
    if dp[i][j] != -float('inf'):
      return dp[i][j]

    res = float('-inf')
    for k in range(i, j, 2):
      op = ops[k]
      l = dfs(i, k - 1)
      r = dfs(k + 1, j)
      if op == '+':
        res = max(res, l + r)
      elif op == '-':
        res = max(res, l - r)
      elif op == '*':
        res = max(res, l * r)

    dp[i][j] = res
    return res

  return dfs(0, n - 1)

示例

对于表达式 "23-45",我们的算法将返回 -31,这是通过对表达式使用乘法优先级的顺序计算出的最大值。

结论

力扣 241 中的优先级问题通过 DFS 和记忆化搜索的巧妙结合得到了优雅的解决。我们的算法不仅有效率,而且通过缓存中间结果避免了不必要的计算。希望本文为读者提供了对这个问题深刻的理解,并激发了他们对解决类似难题的热情。