You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala递归函数内List拼接不生效 二叉树去重算法问题求助

问题根因

Scala 标准库中的List是不可变集合,x :: found操作不会修改原有found列表的内容,只会生成一个头部追加了x的新列表。你当前代码中执行x::found后没有将新生成的列表赋值给变量,也没有传递给后续递归调用,该操作的结果被直接丢弃,外层传入的found始终是初始的空列表,所以看起来拼接操作没有生效。

除此之外你当前的代码结构也存在问题:内部递归函数dfs_helper没有携带更新后的已发现元素集合,所有递归分支共用最外层传入的不变found,自然无法感知到本次遍历新增的元素,也无法正确判断后续节点是否重复。

修复方案

你可以调整dfs_helper的定义,让它接收当前的已发现元素列表作为参数,同时返回处理后的二叉树和更新后的已发现元素集合,保证遍历过程中新增的元素可以被后续递归分支感知到,参考实现如下:

def removeRecurring_dfs(bt: BT): BT = {
  // 辅助函数入参携带当前已发现的元素,返回值同时返回更新后的已发现元素
  def dfs_helper(tree: BT, found: List[Int]): (BT, List[Int]) = {
    tree match
      case Empty => (Empty, found)
      case Node(x, _, _) if found.contains(x) => 
        // 移除重复节点后继续遍历,已发现集合不变
        dfs_helper(rR(tree), found)
      case Node(x, left, right) =>
        // 生成新的已发现集合
        val updatedFound = x :: found
        // 先处理左子树,拿到左子树处理结果和左遍历后的已发现集合
        val (processedLeft, leftFound) = dfs_helper(left, updatedFound)
        // 用左遍历更新后的集合处理右子树
        val (processedRight, finalFound) = dfs_helper(right, leftFound)
        // 返回构造的新节点和最终的已发现集合
        (Node(x, processedLeft, processedRight), finalFound)
  }
  def rR(tree: BT): BT = removeNode(tree, findPath(tree))
  // 初始调用传入空集合,只取处理后的二叉树结果
  dfs_helper(bt, Nil)._1
}

额外优化提示

如果你的二叉树节点数量较多,List的contains操作时间复杂度为O(n),会导致整体算法效率偏低,你可以将found替换为scala.collection.mutable.HashSet,既可以保留修改集合的能力,也能把重复判断的时间复杂度降到O(1)。

内容的提问来源于stack exchange,提问作者ElMagnificent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 10:15:05