2 problems about recursive DFS

时间:2016-02-12 21:41:13

标签: java algorithm depth-first-search

"value001","MD5ofValue001","value002","Value003","Value004","Value005","Value006","Value007"

This is one popular solution on LeetCode, I know DFS theory, I just cannot get it for two points.

  1. In recursive function, there's two options after add a '(', either add another '(' or add some ')', but code is executed from up to down, how can these code process other solutions except ((())). Like (()()), how does it add a ')' after two '('

  2. After finished one solution, add it to list and return, how does it get other solutions after return? Doesn't it mean this method will end after return? New learner about Java, thanks for detailed answers

2 个答案:

答案 0 :(得分:0)

我在backtrack()方法的顶部插入了这一行:

System.out.println("backtrack(" + list + ", \"" + str + "\", " + 
                   open + ", " + close + ", " + max + ")");

这是n = 3生成的内容。我认为这可以帮助您了解递归在这里是如何工作的。

backtrack([], "", 0, 0, 3)
-backtrack([], "(", 1, 0, 3)
--backtrack([], "((", 2, 0, 3)
---backtrack([], "(((", 3, 0, 3)
----backtrack([], "((()", 3, 1, 3)
-----backtrack([], "((())", 3, 2, 3)
------backtrack([], "((()))", 3, 3, 3)
---backtrack([((()))], "(()", 2, 1, 3)
----backtrack([((()))], "(()(", 3, 1, 3)
-----backtrack([((()))], "(()()", 3, 2, 3)
------backtrack([((()))], "(()())", 3, 3, 3)
----backtrack([((())), (()())], "(())", 2, 2, 3)
-----backtrack([((())), (()())], "(())(", 3, 2, 3)
------backtrack([((())), (()())], "(())()", 3, 3, 3)
--backtrack([((())), (()()), (())()], "()", 1, 1, 3)
---backtrack([((())), (()()), (())()], "()(", 2, 1, 3)
----backtrack([((())), (()()), (())()], "()((", 3, 1, 3)
-----backtrack([((())), (()()), (())()], "()(()", 3, 2, 3)
------backtrack([((())), (()()), (())()], "()(())", 3, 3, 3)
----backtrack([((())), (()()), (())(), ()(())], "()()", 2, 2, 3)
-----backtrack([((())), (()()), (())(), ()(())], "()()(", 3, 2, 3)
------backtrack([((())), (()()), (())(), ()(())], "()()()", 3, 3, 3)

虚线表示每次递归调用时的堆栈深度(我通过向String添加额外的backtrack参数来实现此效果,该参数由""&{34}初始化{1}}并且由#34; - &#34连接;每次递归发生时)。

答案 1 :(得分:0)

我认为你对返回的位置以及你的递归函数里面的if语句有点困惑,回溯。

递归函数越来越深入,直到它们到达一个称为基本案例的案例,他们无法继续下去。您应该注意,每个降序级别都是通过调用递归函数来实现的。关键点在于每次调用它都是对单独函数的调用,因此应该单独返回

如果你直觉地,但遗憾地错误地认为是正确的,那么在达到基本情况时你将完全终止递归。相反,如果你有一个如下所示的递归关系,你从函数g中调用f(n),你的重现将像f(n-1),f(n-2),... f一样( 2),f(1),f(0)。当f(0)返回时,它不会将其值返回给g。它实际上会将其值再次返回到函数f,其参数为1.(即基本上遵循它使用的方向,而下降到f(0),仅反向)f(1)将返回到函数f,其参数为2.这将继续,直到您调用f为n的参数为止。只有这样,返回值才会返回g。

private void f(int i){
    if(i == 0) {
        return 0;
    }
    else {
        return f(i-1); 
    }
}

你想到的第一个问题是,如果你得到我上面提到的内容,我认为应该更容易回答。我上面提到的是,简而言之,调用较低级别的递归并不意味着一旦调用较低级别的返回,当前的递归级别也将被终止。如果您了解这一事实,为了回答您的第一个问题,您需要做的就是注意回溯函数中的分支是使用两个 if 函数进行的,而不是单个if& else-if功能。本质上,一旦第一个(即带有'('作为参数)的回溯调用较低级别的递归返回,因为当前递归级别不会终止,将运行单独的if检查,并且如果发现必要(即第二次调用close< open)backtrack。(即这次使用')'和其他相关参数)因为这是在每个递归级别完成的,所以这个函数可以在添加'(''后添加')'次。