"Coding Interview Guide" -- 按照左右半区的方式重新组合单链表

题目

  给定一个单链表的头节点head,链表长度为N,如果N为偶数,那么前N/2个节点算作左半区,后N/2个节点算作右半区;如果N为奇数,那么前N/2个节点算作左半区,后N/2+1个节点算作右半区。

  左半区从左到右依次记为L1 -> L2 -> ...,右半区从左到右依次记为R1 -> R2 -> ...,请将单链表调整成L1 -> R1 -> L2 -> R2 -> ...的形式

  例如,1 -> null,调整成1 -> null

    1 -> 2 -> null,调整成1 -> 2 -> null

    1 -> 2 -> 3 -> null,调整成1 -> 2 -> 3 -> null

    1 -> 2 -> 3 -> 4 -> null,调整成1 -> 3 -> 2 -> 4 -> null

    1 -> 2 -> 3 -> 4 -> 5 -> null,调整成1 -> 3 -> 2 -> 4 -> 5 -> null

    1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null,调整成1 -> 4 -> 2 -> 5 -> 3 -> 6 -> null

my:

 1     public void relocate(Node head)
 2     {
 3       if(head == null || head.next == null)
 4       {
 5         return;
 6      }
7 Node left = getMid(head); // getMid返回的是中间节点 8 Node right = left.next; 9 left.next = null; 10 left = head; 11 12 while(left.next != null) 13 { 14 Node temp = right; 15 right = right.next; 16 temp.next = left.next; 17 left.next = temp; 18 left = temp.next; 19 }       left.next = right; // 右半区的长度总是不小于左半区的长度;若右半区比左半区长,则将长的那部分直接链接到链表的尾部

24 } 25 26 public Node getMid(Node head) 27 { 28 Node temp = head; 29 Node pre = head; 30 Node next = head; 31 while(next.next != null && next.next.next != null) 32 { 33 temp = pre; 34 pre = pre.next; 35 next = next.next.next; 36 } 37 return (next.next == null) ? temp : pre; // 如果N为奇数则返回temp,为偶数则返回pre 38 }

左老师:

 1     public void relocate(Node head)
 2     {    
 3         if(head == null || head.next == null)
 4         {
 5             return;
 6         }
 7         Node mid = head;
 8         Node right = head.next;       // 如果是寻找一般意义上的中间节点,则此处应是right = head;
 9         while(right.next != null && right.next.next != null)
10         {
11             mid = mid.next;
12             right = right.next.next;
13         }
14         right = mid.next;
15         mid.next = null;
16         mergeLR(head, right);
17     }
18 
19     public void mergeLR(Node left, Node right)     // 合并左右半区
20     {
21         Node next = null;
22         while(left.next != null)
23         {
24             next = right.next;
25             right.next = left.next;
26             left.next = right;
27             left = right.next;
28             right = next;
29         }
30         left.next = right;    // 因为右半区的长度总是不小于左半区的,所有直接把多的右半区链接到尾部
31     }

来源:左程云老师《程序员代码面试指南》

原文地址:https://www.cnblogs.com/OoycyoO/p/10991435.html