变量如何在递归中流动?

时间:2017-07-11 01:29:37

标签: java recursion

这是一个LeetCode问题,例如,要求的是总结两个链接的数字
输入:(2 - > 4 - > 3)+(5 - > 6 - > 4)
输出:7 - > 0 - > 8

问题:
下面的代码使用递归方法,每次递归调用(第三行到最后一行)都会构造一个新的result,我很难理解为什么旧的result不会被覆盖新的result?是因为这些result属于不同的范围,例如scope1.result,scope2.result?

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public ListNode op(ListNode l1, ListNode l2, int carry) {

    if (l1==null && l2==null) {
        return carry==0 ? null: new ListNode(carry);
    }

    if (l1==null && l2!=null) {
        l1 = new ListNode(0);
    }

    if (l1!=null && l2==null) {
        l2 = new ListNode(0);
    }

    int sum = l1.val + l2.val + carry;
    ListNode result = new ListNode(sum % 10);
    result.next = op(l1.next, l2.next, sum / 10);
    return result;
}

1 个答案:

答案 0 :(得分:0)

本地变量对于调用是唯一的。因此,如果您使用长度为3的两个链接列表执行此操作,则您将拥有4个resultsum,这些列表位于其调用实例的本地。

事实上,递归函数在Java中没有得到任何特殊处理。每个函数都有自己的局部变量和参数。例如:

public int test1(int n) {
  int y = 2*n;
  return y + test2(n+1);
}

public int test2(int n) {
  int y = 3*n;
  return y - n/3;
}

这根本不是递归的,但它们都有变量ny。如果变量不是本地test1(3),那么23就会test2改变test1 y,但ny {1}}是每个方法调用的本地调用,y保留6,结果为15

如果一个方法调用自身,如果为该运行获取一组新变量,并且当它返回时,callee的变量与之前相同。

这适用于变量绑定而不是对象。如果要将对象传递给方法并且它突变对象而不是绑定,则更改将影响指向该对象的所有变量。例如

// Bad implementation of rounding up to nearest 10 by mutating box
public int test(int[] n) {
  if( n[0] % 10 == 0)
    return n[0];
  n[0]++; // mutates array not binding
  return test(n);
}

更好的递归版本:

public int test(int n) {
  if( n % 10 == 0)
    return n;
  return test(n+1);
}