【问题标题】:Reverse a singly linked list recursively by dividing linked list in half in each recurrence通过在每次递归中将链表分成两半来递归地反转单链表
【发布时间】:2021-03-27 08:12:10
【问题描述】:

如何在 java 中编写一个函数,通过将单链表分成两半来反转单链表,这意味着第一部分为 (n/2) 个节点,其余为第二部分(n 是喜欢列表的大小),直到它到达一个节点,然后合并这个分割的部分。在每个划分中允许使用两个新的链接列表,但不允许使用列表节点。该函数必须是void,并且该函数没有无参数。我有 n, head 和 tail 的主链表。

我在网站上找到了这段代码,但它没有将链接列表分成两半,所以它没有帮助。

static ListNode reverseR(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }

    ListNode first = head;
    ListNode rest = head.next;

    // reverse the rest of the list recursively
    head = reverseR(rest);

    // fix the first node after recursion
    first.next.next = first;
    first.next = null;

    return head;
}

【问题讨论】:

  • 这似乎效率很低,你有实际用途还是只是一个练习?
  • 这只是一个练习

标签: java algorithm linked-list


【解决方案1】:

因为您使用的是链表,所以您建议的方法不太可能有效。确定中点的位置是线性时间操作,即使列表的大小已知,您仍然必须迭代到中点。因为您在递归树的每个节点处都有一个线性项,所以整体性能将为 O(n lg n),比您提供的代码的 O(n) 范围要慢。

话虽如此,您仍然可以通过以下策略反转列表:

 Step 1: Split the list L into A (the first half) and B (the second half).
 Step 2: Recurse on each of A and B. This recursion should bottom out 
         when given a list of length 1.
 Step 3: Attach the new head of the reversed A to the new tail of the reversed B.

您可以看到,首先,我们的列表是 AB。然后我们递归得到 A' 和 B',每个都是半列表的反转版本。然后我们输出新的反向列表 B'A'。原来 A 的第一个元素现在是整个列表的最后一个元素,而原来 B 的最后一个元素现在是第一个整体。

【讨论】:

  • 问题在于,递归传递新列表的函数没有参数。
  • 想必你的函数是允许把列表作为参数的吧?否则它将如何反转列表?
猜你喜欢
  • 2012-11-05
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 2010-09-26
相关资源
最近更新 更多