【问题标题】:Recursion is not preserving values in javascript递归不保留javascript中的值
【发布时间】:2021-06-03 18:54:56
【问题描述】:

我目前正在尝试解决这个问题:https://leetcode.com/problems/maximum-depth-of-binary-tree/

这是我的代码:

function TreeNode(val, left, right) {
    this.val = (val===undefined ? 0 : val)
    this.left = (left===undefined ? null : left)
    this.right = (right===undefined ? null : right)
 }
 
 const NINE = new TreeNode(9);
 const FIFTEEN = new TreeNode(15);
 const SEVEN = new TreeNode(7);
 const TWENTY = new TreeNode(20, FIFTEEN, SEVEN);
 const THREE = new TreeNode(3, NINE, TWENTY);


var maxDepth = function(root) {
    let max = 0;
    helper(root, max, 0);
    console.log(max, 'max')
    return max + 1;
};

function helper(root, max, i) {
    if(root === null) return max;
    if(max < i) {
        max = i;
     }
    
     const maxLeft = helper(root.left, max, i+1); 
     const maxRight = helper(root.right, max, i+1);
    
    return max = maxLeft > maxRight ? maxLeft : maxRight;
}

maxDepth(THREE);

至此,我有 3 个问题:

1) 我不明白这一行:

return max = maxLeft > maxRight ? maxLeft : maxRight; //2

这里,maxDepth 函数中的max 值不会也更新吗?在这种情况下,我认为应该是2。但是,当我在原始函数中 console.logged 时,我收到了0 结果。为什么会发生这种情况?如何保留从调用堆栈返回的最大值?

  1. 最初我在下面写了这两行:
const maxLeft = helper(root.left, max, i+1); 
const maxRight = helper(root.right, max, i+1);

作为:

helper(root.left, max, i+1); 
helper(root.right, max, i+1);

因为我的逻辑是在这个条件之后:

if(max < i) {
   max = i;
}

然而,当函数返回调用堆栈时,max 似乎被设置回 0。为什么 max 的值没有被保留,我们如何保留该值?

  1. 我仍然对上面的两行感到困惑:
const maxLeft = helper(root.left, max, i+1); //1
const maxRight = helper(root.right, max, i+1); //2

这里,maxLeft 和 maxRight 的值保留为 1 和 2。当我们返回调用堆栈时,为什么不将它们设置回 0?

【问题讨论】:

    标签: javascript recursion tree binary-tree callstack


    【解决方案1】:

    当您将数字发送到函数并在函数内更改它时,它只会在该函数内更改 -

    var maxDepth = function(root) {
        let max = 0;            // define a number, max
        helper(root, max, 0);   // call helper with root, max, and 0
        console.log(max, 'max') // max will always be 0, helper cannot change it
        return max + 1;         // this will always be 0 + 1
    };
    

    在下面的helper 中看到它有一个return 声明?这意味着一个 新 值即将出现。在上面的代码中,你不用它做任何事情。它被简单地丢弃并执行到下一行 -

    function helper(root, max, i) {
        if(root === null) return max;
        if(max < i) {
            max = i;
         }
        
         const maxLeft = helper(root.left, max, i+1); 
         const maxRight = helper(root.right, max, i+1);
        
        return max = maxLeft > maxRight ? maxLeft : maxRight; // <-
    }
    

    因此您可以通过在 maxDepth 中重新分配 max 来更新它 -

    var maxDepth = function(root) {
        let max = 0;
        max = helper(root, max, 0); // <- get new max from helper
        console.log(max, 'max')
        return max + 1;
    };
    

    这可能会解决您的一些误解,但遗憾的是它并不能修复代码。递归是一种函数式遗产,因此将其与函数式风格一起使用会产生最佳结果。这意味着要避免诸如突变、变量重新分配和其他副作用之类的事情。

    const empty =
      {}
     
    const node = (val, left = empty, right = empty) =>
      ({ val, left, right })
    
    function max(a, b)
    { if (a > b)
        return a
      else
        return b
    }
     
    function depth(t)
    { if (t === empty)
        return 0
      else
        return 1 + max(depth(t.left), depth(t.right))
    }
    
    const mytree = 
      node(3, node(9), node(20, node(15), node(7)))
      
    console.log(depth(mytree))
    // 3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-01
      • 2023-01-15
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多