首页 > 解决方案 > LeetCode 988:回溯和深度优先搜索(DFS)的区别

问题描述

我对LeetCode 988(从叶子开始的最小字符串)中的回溯解决方案和 DFS 解决方案感到困惑。

如果使用 StringBuilder 实现,则需要这行代码:sb.deleteCharAt(sb.length() - 1),而使用 String 实现时,不需要该行。

任何人都可以帮助解决我的困惑吗?

回溯(使用 StringBuilder)

String ans = "";

public String smallestFromLeaf(TreeNode root) {
    helper(root, new StringBuilder());
    return ans;
 }

private void helper(TreeNode root, StringBuilder sb) {
    if (root == null) return;
    sb.append((char)('a' + root.val));
    if (root.left == null && root.right == null) {
    String candidate = sb.reverse().toString();
    if (ans == "" || candidate.compareTo(ans) < 0) {
        ans = candidate;
        sb.reverse();
    }

    helper(root.left, sb);
    helper(root.right, sb);
    sb.deleteCharAt(sb.length() - 1);
}

DFS(使用字符串)

String ans = "";

public String smallestFromLeaf(TreeNode root) {
    helper(root, "");
    return ans;
}

private void helper(TreeNode root, String s) {
    if (root == null) return;

    s = (char)('a' + root.val) + s;
    if (root.left == null && root.right == null) {
        String candidate = s;
        if (ans == "" || candidate.compareTo(ans) < 0) {
            ans = candidate;
        }
        return;
    }

    helper(root.left, s);
    helper(root.right, s);
}

标签: javaalgorithmdepth-first-searchbacktracking

解决方案


字符串在 Java 中是不可变的,所以这意味着这一行,

s = (char)('a' + root.val) + s;

将创建递归函数接收的新字符串对象。因此,回溯解决方案通常没有“撤消”步骤。而在回溯解决方案中,只创建并传递了一个 StringBuilder 对象。当我们从回溯解决方案中的基本情况返回时(即到达叶节点),我们必须撤消将字符添加到字符串构建器的步骤。

我建议您将打印语句添加到sb回溯解决方案的状态以及sDFS 中的值,并查看它如何更改递归的每一步。


推荐阅读