【问题标题】:Runner technique to combine two equal Linked Lists合并两个相等的链表的 Runner 技术
【发布时间】:2015-08-13 07:09:33
【问题描述】:

所以,我在这里面临一个疑问。

我正在阅读《破解编码面试》这本书。下面的文字写在那里。

假设你有一个链表a1->a2....->an->b1->b2....bn,你想把它重新排列成a1->b1->a2->b2->.....an->bn。你不知道链表的长度,但你只知道它是一个偶数。

(这里两个链表长度相同)

你可以让一个指针 p1(快速指针)每两个元素移动一次 p2 每移动一次。当 p1 到达链表的末尾时,p2 将在端点处。然后,将 p1 移回前面并开始“编织”元素。在每次迭代中,p2 选择一个元素并将其插入到 p1 之后。

我不明白当 p1 到达链表的末尾时,p2 会在中点。如果n = 3(长度= 6),这就是我的想象。下面的每个步骤都代表一个迭代。

1. a1 (p1, p2)->a2->a3->b1->b2->b3 
2. a1->a2 (p2)->a3 (p1)->b1->b2->b3 
3. a1->a2->a3 (p2)->b1->b2 (p1)->b3 
4. Index out of bounds error because p2 now points to a node after b3.

我是不是走错地方了?

【问题讨论】:

  • Suppose you had a linked list a1->a2....->an->b1->b2....bn, and you want to rearrange it into a1->a2->...an->b1->b2....->bn. ?
  • 抱歉打错了。更正了问题。我的错。
  • 问题的标题与问题有什么关系。是的,这种技术可以用来组合两个链表。但是,在 Runner Technique 部分中没有提到两个链表。因此,编辑标题可能是一种改进。

标签: algorithm linked-list


【解决方案1】:

从第二个位置开始 p2。

a1(p1)-> a2 (p2) -> a3 -> a4 -> b1 -> b2 -> b3 -> b4  
a1-> a2 (p1) -> a3 -> a4 (p2)-> b1 -> b2 -> b3 -> b4  
a1-> a2  -> a3(p1) -> a4 -> b1 -> b2(p2) -> b3 -> b4  
a1-> a2  -> a3 -> a4(p1) -> b1 -> b2 -> b3 -> b4(p2)  

【讨论】:

  • 这里的编织到底是什么意思?
  • 编织是问题的意图,意味着重新排列数组。
【解决方案2】:

n = 2。我们从一个列表开始:

a1 -> a2 -> b1 -> b2

p1 是一个“快速”指针,最初指向head 的后继者。
p2 成为最初指向头部的“慢”指针。

      p1
a1 -> a2 -> b1 -> b2
p2

我们将p1 移动两位,p2 移动一位,直到p1 到达列表末尾(没有下一个)。

                  p1
a1 -> a2 -> b1 -> b2
      p2

p1 移回头部。

p1                  
a1 -> a2 -> b1 -> b2
      p2

提前p2.

p1                  
a1 -> a2 -> b1 -> b2
            p2

“编织”开始。

p2 指向的元素移到p1 之后。在插入元素后前进p1

            p1                  
a1 -> b1 -> a2 -> b2
                  p2

p2 指向的元素移到p1 之后。在插入元素后前进p1

                       p1      
a1 -> b1 -> a2 -> b2  
                  p2

p1 为空,终止。

【讨论】:

  • 很好的解释。谢谢您的帮助。 :)
【解决方案3】:

你可以简单地使用Java来实现:

public static void findMidElOfLinkedList(FindMidElementOfLinkedList findMidElementOfLinkedList) {
    Node node = findMidElementOfLinkedList.head;
    Node slow = node;
    Node fast = node;

    while (fast != null && fast.next != null) {
        fast = fast.next.next; // increase 2
        slow = slow.next; // increate 1
    }
    System.out.println(slow.data);
    /*
    * Slow runner goes at a pace of 1 element per move, fast runner goes 2 elements per move.
    When the fast runner reaches the end of the linked list, then slow runner is sitting at the middle. Testing this out for one/two middle cases work.
    Time O(N), faster than the previous brute force method, Space: O(1).
    * */
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-14
    • 2021-10-21
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多