有效地重新排序链接列表

时间:2015-08-05 11:56:16

标签: algorithm linked-list

我在接受采访时得到了这个问题,如下:

如果我有这样的链接列表,

1→2→3→4-将5-→6

我必须把它转换成,

1→6-> 2→5→3→4

如果是,就像这样,

1→2→3→4-将5-> 6-大于7

我必须将其转换为

1→7-> 2→6-> 3→5→4

而且,最重要的是,我必须修改原始链表,我不能创建新的链表。我想到了这个递归。但是,我无法真正解决它。而且,它们的约束条件是,此函数只能具有链表的头部。

3 个答案:

答案 0 :(得分:3)

这可以在线性时间O(n)内完成,通常在访谈期间(不幸的是)比解决方案的稳健性更重要。

你可以通过将原始列表拆分为两个(as)同等大小(尽可能)的列表,然后反转第二个并逐个元素地合并它们(第一个列表中的第一个元素,第二个列表中的第二个元素)来实现等等)。您不需要太多额外空间,因为您可以使用现有指针。

例如:

1->2->3->4->5->6

1->2->3 and 4->5->6 // after split, 3 points to null, 4 is head of second list
1->2->3 and 4<-5<-6 // after reorder
1->6->2->3 and 4<-5 // first phase of merge
1->6->2->5->3 and 4 // second phase of merge
1->6->2->5->3->4    // last phase of merge

您可以使用running pointer找到分割点。遍历列表时,一个指针一次指向一个节点,一个指向两个节点。当快速指针到达末尾(null)时,较慢的指针将在分割之前,分割之前的节点必须指向null而不是下一个节点(在我们的例子中代替4)和下一个节点(4)成为第二个名单的负责人。

反转第二个列表并合并是简单的指针交换。

请注意空指针: - )

答案 1 :(得分:2)

这可以使用递归算法完成。您需要以“螺旋式”的方式遍历列表。方式(先到先到后)。所以,我的想法是分离列表的第一个和最后一个元素,连接它们并递归地对其余元素做同样的事情。

这是算法的大致轮廓:

modifyList(head):
    if head.next == null or head.next.next == null: # when the list contains 1 or 2 elements, keep it unchanged
        return head

    nextHead = head.next # head of the list after removing head and last item
    last = head.next
    beforeLast = head
    while last.next != null: # find the last item, and the item before it
        beforeLast = last
        last = last.next

    head.next = last # append last item after first
    beforeLast.next = null # remove the last item from list
    last.next = modifyList(nextHead) # recursively modify the 'middle' elements and append to the previous last item
    return head

答案 2 :(得分:0)

这是一种递归方式。

创建一个函数nreverse,用于反转链接列表。 Common Lisp具有此功能。

盯着列表的头部,如果列表长于一个元素,nreverse在第一个元素之后的列表。在Scheme中:

(setcdr listx (nreverse (cdr listx)))

递归列表的下一个子列表。这是Common Lisp中的全部内容:

? (defun munge (listx)
  (let ((balx (cdr listx)))
    (if (null balx)
        listx
        (progn (rplacd listx (nreverse balx))
               (munge (cdr listx))
               listx))))
MUNGE
? (munge '(1 2 3))
(1 3 2)
? (munge '(1 2 3 4 5 6))
(1 6 2 5 3 4)
? (munge '(1 2 3 4 5 6 7))
(1 7 2 6 3 5 4)
?