【问题标题】:Backtracking a recursive problem to solve balanced parentheses回溯递归问题以解决平衡括号
【发布时间】:2019-10-22 03:54:22
【问题描述】:

我需要了解如何从递归函数中回溯。我知道对于阶乘或斐波那契等基本函数是如何完成的。这个问题我不明白。

我尝试在第二个递归调用中消除其他条件,但它也会生成所有可能的括号集,包括不平衡的括号集。

public final class Example {
    public static void parentheses(int left, int right, String str) {
        if (left == 0 && right == 0) {
            System.out.print(str);
            System.out.print(", ");
        }

        if (left > 0) {
            str += "(";
            parentheses(left - 1, right, str);
        }

        if (right > 0 && right > left) {
            str += ")";
            parentheses(left, right - 1, str);
        }
    }

    public static void main(String[] args) {
        parentheses(3, 3, "");
    }
}

我希望结果是所有可能的平衡括号集但是在每次递归调用之后,我都会得到 1 个额外的左括号。预期输出是:

((())), (()()), (())(), ()(()), ()()(),

我得到的输出是:

((())), ((()()), ((()()(), (()(()), (()(()(),

【问题讨论】:

  • 回溯和递归调用是有区别的。递归不是回溯。
  • 如果你使用递归,你所说的回溯不是回溯。您正在考虑的是“提前返回”:一旦您获得“期望的结果”或“已知永远不会产生期望的结果”,您就会返回。在代码注释中:不要传入str,使函数return str,然后在运行时聚合这些返回值。在一个为 0 另一个为 1 之前不要返回任何内容,然后返回适当的字符串,然后 递归步骤之后,组装成您返回的更大的字符串。
  • 看不到输入是什么...

标签: java recursion backtracking parentheses


【解决方案1】:

问题出在下面。

 str += "(";

您每次都在创建一个新的字符串对象并在递归调用中传递它。结果,每个递归调用对字符串对象都有不同的值,因此您预期的递归失败。字符串在 Java 中是不可变的。

将您的代码更改为以下内容:

        public static void parentheses(int left, int right, String str) {

        if ( right==0 && left==0) {
            System.out.print(str);
            System.out.print(", ");

        }
        if (left > 0) {
            parentheses(left-1, right, str +"(" ); // New object will be created but its value will be dereferenced from the old one and attached to the new one.
            // As a result all our manipulation of string we did will be saved.
        }
        if ( right >0 && right > left) {
            parentheses(left, right - 1, str +")" );
        }
    }

输入:

parentheses(3,3,""); // Function call

输出:

((())), (()()), (())(), ()(()), ()()(),

【讨论】:

    猜你喜欢
    • 2020-06-30
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 2011-08-15
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    相关资源
    最近更新 更多