微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

DFS递归解决问题是如何进行的?

如何解决DFS递归解决问题是如何进行的?

问题出在这里

有n个非负整数。我们想适当地增加或减少这些数字以得出目标数字。例如,要使数字1等于[1,1,1,1,1],可以使用以下五种方法

-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3

编写解决方函数,以数组编号,目标编号和目标作为参数给出时,通过适当地增加和减去这些数字来返回生成目标编号的方法

限制

  • 给出的数字是2个或20个以下。
  • 每个数字都是1到50之间的自然数。
  • 目标数字是1到1000之间的自然数。

I / O示例

numbers: [1,1,1]
target: 3
return: 5

方法

                                    1

                                  /   \

                               -1       1

                             /   \     /   \

                           -1     1  -1     1
                           
                           -1     1   1     3

以DFS方式找到了这种方法,检查所有情况,如果数字的组合等于目标数字,则进行加法或减法计算。

以下代码

def solution(numbers,target):
    total = 0
    num_len = len(numbers)

    def dfs(index=0):
        if index < num_len:
            numbers[index] *= 1
            print('positive / index',index,numbers)
            dfs(index + 1)

            numbers[index] *= -1
            print('negative / index',numbers)
            dfs(index + 1)

        else:
            if sum(numbers) == target:
                nonlocal total
                total += 1
                print('matched / index',numbers)

    dfs()

    return total

但是,我想知道它如何运行,控制台日志记录也是如此。

positive / index 0 [1,1]
positive / index 1 [1,1]
positive / index 2 [1,1]
positive / index 3 [1,1] 
positive / index 4 [1,1]
negative / index 4 [1,-1]
matched / index 5 [1,-1]
negative / index 3 [1,-1,-1] ### how come this index all of sudden becomes 3? ###
positive / index 4 [1,-1]
                ...

我有点理解直到索引匹配递归/索引5的增量 但不太确定为什么下次会变成3。

解决方法

日志格式可能会使您感到困惑。 5点之后,不再需要进行递归调用,因此下一个打印行与一个较旧的堆栈框架相关联,该框架一直坐着等待其子节点解析,然后再探索下一个递归调用链。

如果添加缩进,您将更清楚地看到父子关系:

print("  " * index + 'positive',numbers)
0 1 2 3 4 5     stack depth
===========================
positive [1,1,1]
  positive [1,1]
    positive [1,1]
      positive [1,1]
        positive [1,1]
        negative [1,-1]
          matched [1,-1]
      negative [1,-1,-1]  <-- here's the call you asked about
      ... calls continue ...

在这里,您可以看到您的问题所在的否定分支回到了深度3,并且不是matched的子级。在matched调用之后,没有更多的子节点可以探索,并且堆栈弹出回到父节点,而父节点也没有其他节点可以探索并弹出回到深度2的父节点,该节点的深度为2。 1}}的子调用链进行探索,并产生了对深度3的第二个调用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。