LeetCode: Reorder List
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}
, reorder it to {1,4,2,3}
.
我想到的方法是用stack记录下要处理的node,就是从中间开始,后面的node都压入stack。然后再把他们一一插入到原来的list中。
比较需要小心的地方时,节点个数为奇数还是偶数的情况不同。因为要给最后一个node的next赋值为null。
1 public void reorderList(ListNode head) { 2 int n = 0; 3 ListNode start = head; 4 while (head != null) { 5 head = head.next; 6 n++; 7 } 8 int t = n/2; 9 head = start; 10 Stack<ListNode> s = new Stack<ListNode>(); 11 for (int i=0; i < n-t; i++) { 12 head = head.next; 13 } 14 for (int i=n-t; i<n; i++) { 15 s.push(head); 16 head = head.next; 17 } 18 19 head = start; 20 21 while(!s.isEmpty()) { 22 ListNode x = s.pop(); 23 x.next = head.next; 24 head.next = x; 25 if (s.isEmpty() && n%2 == 0) head.next.next = null; 26 else head = head.next.next; 27 } 28 if (n%2 != 0) head.next = null; 29 }
第二种方法,不需要额外空间。还是先找到list的中点。然后把中点后面的list反转。最后将反转的list插入到原来的list中。
需要注意的地方:1. 如何做单链表的反转。在头结点后面插入的方法需要两个指针,一个指向已排好序的最后一个元素,一个指向它的next,也就是即将操作的node。循环终止条件时next为空。
2. 是最后插入的时候的终止条件。在奇数的时候cur == null, 偶数的时候是start == null。
1 public void reorderList(ListNode head) { 2 int n = 0; 3 ListNode start = head; 4 while (head != null) { 5 head = head.next; 6 n++; 7 } 8 if (n <= 2) return; 9 int t = n/2; 10 head = start; 11 for (int i=0; i <n-t-1; i++) { 12 head = head.next; 13 } 14 ListNode prev = head.next; 15 ListNode cur = prev.next; 16 17 while (cur != null) { 18 prev.next = cur.next; 19 cur.next = head.next; 20 head.next = cur; 21 cur = prev.next; 22 } 23 24 cur = head.next; 25 while (cur != null && start != null) { 26 head.next = cur.next; 27 cur.next = start.next; 28 start.next = cur; 29 30 start = start.next.next; 31 cur = head.next; 32 } 33 }