使用递归时为什么不能在Java链表遍历中返回Object?

时间:2016-01-14 15:29:49

标签: java oop object recursion linked-list

在Cracking the Coding Interview(第6版)一书中,一个问题要求我:

  

实现算法以查找单链表的最后一个元素

后来,作者声称:

  

不幸的是,我们无法使用正常的return语句传回一个节点和一个计数器。

她在上面的语句中引用了Java语言。她后来证明我们只能在Java中打印单链表中的第k个元素。

我的问题是:当递归弹出帧时,为什么我们不能传回一个节点?为什么我们不能在递归函数中添加另一个参数,以便将该参数设置在我们正在寻找的节点的正确时间(即当index =第k项时)?我从昨晚开始就一直在考虑这个问题,而我却无法绕过它。

提供的示例答案如下所示:

int printKthToLast (LinkedListNode head, int k) {

    if(head == null) {
        return 0;
    }

    int index = printKthToLast(head.next, k) + 1;
    if (index == k) {
        System.out.println(k + "th to last node is " + head.data);
    }
    return index;
}

2 个答案:

答案 0 :(得分:3)

当你说我们可以"在递归函数中添加另一个参数以便在正确的时间设置参数时,你是对的"。例如,此功能的工作方式与您发布的解决方案相同:

private void printKthToLast(LinkedListNode head, int k, int index) {

    if(head == null) {
        return;
    }

    if(index >= k) {

        System.out.println(head.data);
    }

    printKthToLast(head.next, k, ++index);
}

我的猜测是,作者试图说明递归通常" 将问题划分为子问题,解决这些子问题,结合结果" (即经典的分而治之方法)。在这种情况下,当我们在" next"上调用递归函数时,将问题划分为子问题。因为我们越接近基本情况(head == null)。要合并结果是索引,必须递归递增以确定何时必须打印节点。这就是索引建立函数返回类型(int)的原因。这是递归地解决问题的正确方法。你建议的是一种可能性,但通过" index"作为参数既不是将问题划分为子问题也不是将结果组合

此外,考虑到在Java中,方法不仅可以通过它们的名称来识别,还可以通过它们的输入参数,返回类型等来识别。因此,这两种方法......

private int printKthToLast(LinkedListNode head, int k)

private void printKthToLast(LinkedListNode head, int k, int index)

...完全不同,即使它们具有相同的名称(这称为多态)。因此,在同一解决方案中包含这两种方法不会是递归。

答案 1 :(得分:0)

LinkedListNodeLinkedList内部使用。

LinkedList上没有允许检索内部LinkedListNode(实际上称为Entry)的公开方法

因此,给定LinkedList,您无法访问内部节点。

然而,如果只是通过列表,你可以简单地使用迭代器并递归它:

int printKthToLast (Iterator<E> it, int i) {
    if(!it.hasNext()) {
       return 0;
    }
    E e = it.next();
    // ...
}