【问题标题】:Print all Valid Parenthesis given number n打印所有给定数字 n 的有效括号
【发布时间】:2023-03-25 12:51:01
【问题描述】:

我对一个众所周知的问题的堆栈状态有点困惑 , Valid Permutation of Parenthesis

互联网上有很多文章和解决方案,其中一个简单的解决方案是

static void allParen1( int l, int r, int n, String str ) {
    if( r == n ) {
        System.out.println(str + " <" + l + ": " + r + ">");
        return;
    }

    if( l < n ) {
        allParen1( l + 1, r, n, str +"(" );
    } 

    if( r < l ) {
        allParen1( l, r + 1, n, str + ")");
    }
}

如果我为此代码绘制递归树是

但我不清楚每个子树是如何正确启动的。

例如,沿着图中最左边的子树向下走后, 它会上升到((,然后开始第二个最左边的子树((),...

下面我画了递归树的一部分栈状态。

1.我的第一个问题是堆栈如何在第一个堆栈中仅弹出到((( (1) 这对应于上树然后开始堆栈中的第二个最左子树(2) 在代码中?

为什么堆栈不会弹出到 ((()((())( 之类的其他内容 在给定代码的第一个堆栈 (1) 中?

也许我还不太清楚递归和回溯是如何工作的。

2.他们说这个问题是使用回溯。 如果在去之前不满足某个条件,则回溯正在发生 再往下到一棵recustion树,它不会长袍而只是分支出来 到一个不同的子树,比如 N-Queen 问题。

即使这个问题没有停止向下递归树的条件。 这怎么叫回溯问题?

【问题讨论】:

  • 1.你有一个条件 l &lt; n 这就是为什么在 (((((() 节点中没有分支
  • 尝试追踪代码。使用调试器逐步完成。插入print 语句以显示有用的变量值(函数入口、函数出口和分支点)。

标签: algorithm recursion


【解决方案1】:

如果您仔细跟踪执行,您会发现堆栈确实弹出到((()),然后到(((),然后到(((,最后是(( .. . 这是有第二个选择(可能的分支)的最早点。请记住n=3:当您第一次回溯到((()) 时,您已经处理了添加一个RPAREN,并且没有更多可用的LPARENS ——您已经使用了所有三个。同样,您必须将堆栈返回((,在那里您可以最终做出与您刚刚处理的((())) 分支不同的选择:您刚刚弹出第三个 LPAREN,现在您可以用 RPAREN 替换它并前往一个新分支。

【讨论】:

    猜你喜欢
    • 2017-05-24
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多