【问题标题】:Use of variables in recursion在递归中使用变量
【发布时间】:2016-04-17 08:50:27
【问题描述】:

我已经编写了下面的代码来反转链表的前 K 个节点,它在 Reversing first K nodes of Linked List,Why recursion executing twice for last iteration 中解决了一些问题,现在它可以正常工作但是为什么当我尝试使用变量“k”时它会导致链表中的循环而不是“if”条件下的“presentCounter”,是什么原因?以及如何避免?

 /*
 * Condition K <= Length of linked list.
 *  node = null
 *  nextNode headNode of the linked list
 */

public void reverseNode(Node node, Node nextNode, int k) {

    int presentCounter = k;
    if (k > 1) {
        k = k - 1;
        this.reverseNode(nextNode, nextNode.next, k);
    }

    if (presentCounter == 1) {
        this.kNode = nextNode.next; // Saving K's Next Node
        this.headNode = nextNode; // Setting K node as head node
    }
    if (node == null) {
        nextNode.next = this.kNode;
    } else

        nextNode.next = node;
}

【问题讨论】:

    标签: algorithm sorting recursion data-structures linked-list


    【解决方案1】:

    因为presentCounter 稍后也用于检查与if (presenceCount == 1) 交换的最后一个元素。
    如果你天真地摆脱k 并改用presentCounter

    if (presentCounter > 1) {
        presentCounter = presentCounter - 1;
        this.reverseNode(nextNode, nextNode.next, presentCounter);
    }
    

    因为现在presentCounter 已经递减,检查最后一个要交换的元素会触发之前的一项。

    例如在列表[a b c d] 中,当请求交换前三个元素时,检查c 应该为真,因此this.kNoded
    如果前一步为真,即对于b,则this.kNodec(并且头部设置为b)。
    当以相反的顺序(c b a)链接元素时,旧的head1链接到this.kNode,所以我们最终得到两个不同的结果:

    • 正确this.kNoded
      c b a d

    • 不正确this.kNodec
      b a c b a c ...

    第二个是循环。
    不过,您可以轻松摆脱k

    if (presentCounter > 1)
        this.reverseNode(nextNode, nextNode.next, presentCounter-1);
    

    为了更好地理解发生了什么,这里有一张图片。

    你要明白有两个阶段:遍历阶段 (当进行递归调用时)和构建阶段(当递归 电话已返回)。
    所以每次调用都被描绘了两次。

    pc代表presentCounter


    1第一个元素,nodenull时保存在nextNode中的元素,即函数的第一次调用。

    【讨论】:

      【解决方案2】:

      当 k 为 2 时,它进入第一个条件 (k > 1)

      那么它将递减k并递归

      然后递归结束后会继续下一行。

      k=k-1 给出 1,因此“if (k == 1)”将在第二个条件内执行操作以及在同一次传递中。

      通过在减去一个之前将 k 保存到 presentCounter 中,然后检查 presentCounter == 1,您可以避免这个额外的任务被执行两次(一次在递归调用中,因为现在 k == 1,然后在递归完成时再次执行) .

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-20
        • 1970-01-01
        • 2016-05-31
        • 2014-07-08
        • 2016-04-13
        • 2022-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多