[LeetCode] 143. Reorder List

重排链表。题意很简单,

Given a singly linked list LL0→L1→…→Ln-1→Ln,
reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

You may not modify the values in the list's nodes, only nodes itself may be changed.

Example 1:

Given 1->2->3->4, reorder it to 1->4->2->3.

Example 2:

Given 1->2->3->4->5, reorder it to 1->5->2->4->3.

思路也很直观,但是代码容易错,算是链表题里面的综合题吧,有链表的快慢指针fast-slow pointer,反转reverse,和merge两个链表三个技能点的考察。找快慢指针的时候记得设一个temp node,因为slow停下的地方会是second half的起点,这个temp指针会停在first half的尾部。

时间O(n)

空间O(1)

JavaScript实现

 1 /**
 2  * @param {ListNode} head
 3  * @return {void} Do not return anything, modify head in-place instead.
 4  */
 5 var reorderList = function(head) {
 6     if (!head || !head.next) return;
 7     let fast = head;
 8     let slow = head;
 9     while (fast && fast.next) {
10         fast = fast.next.next;
11         slow = slow.next;
12     }
13     let second = reverseList(slow.next);
14     slow.next = null;
15     let first = head;
16     while (second) {
17         let temp = second.next;
18         second.next = first.next;
19         first.next = second;
20         first = first.next.next;
21         second = temp;
22     }
23 };
24 
25 var reverseList = function(head) {
26     let pre = null;
27     while (head !== null) {
28         let next = head.next;
29         head.next = pre;
30         pre = head;
31         head = next;
32     }
33     return pre;
34 };

Java实现

 1 class Solution {
 2     public void reorderList(ListNode head) {
 3         if (head == null || head.next == null) {
 4             return;
 5         }
 6         ListNode temp = null;
 7         ListNode slow = head;
 8         ListNode fast = head;
 9         ListNode l1 = head;
10         while (fast != null && fast.next != null) {
11             temp = slow;
12             slow = slow.next;
13             fast = fast.next.next;
14         }
15         temp.next = null;
16         ListNode l2 = reverse(slow);
17         merge(l1, l2);
18     }
19 
20     private ListNode reverse(ListNode head) {
21         ListNode prev = null;
22         while (head != null) {
23             ListNode next = head.next;
24             head.next = prev;
25             prev = head;
26             head = next;
27         }
28         return prev;
29     }
30 
31     private void merge(ListNode l1, ListNode l2) {
32         while (l1 != l2) {
33             ListNode n1 = l1.next;
34             ListNode n2 = l2.next;
35             l1.next = l2;
36             if (n1 == null)
37                 break;
38             l2.next = n1;
39             l1 = n1;
40             l2 = n2;
41         }
42     }
43 }

另一种Java实现,把getMiddle写成一个函数,注意while循环的部分

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode() {}
 7  *     ListNode(int val) { this.val = val; }
 8  *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 9  * }
10  */
11 class Solution {
12     public void reorderList(ListNode head) {
13         // corner case
14         if (head == null || head.next == null) {
15             return;
16         }
17         // normal case
18         ListNode middle = findMiddle(head);
19         ListNode first = head;
20         ListNode second = middle.next;
21         middle.next = null;
22         second = reverse(second);
23         merge(first, second);
24     }
25 
26     private ListNode findMiddle(ListNode head) {
27         ListNode slow = head;
28         ListNode fast = head;
29         while (fast != null && fast.next != null) {
30             slow = slow.next;
31             fast = fast.next.next;
32         }
33         return slow;
34     }
35 
36     private ListNode reverse(ListNode head) {
37         ListNode pre = null;
38         while (head != null) {
39             ListNode next = head.next;
40             head.next = pre;
41             pre = head;
42             head = next;
43         }
44         return pre;
45     }
46 
47     private void merge(ListNode left, ListNode right) {
48         ListNode leftTemp;
49         ListNode rightTemp;
50         while (left != null && right != null) {
51             leftTemp = left.next;
52             rightTemp = right.next;
53             left.next = right;
54             right.next = leftTemp;
55             left = leftTemp;
56             right = rightTemp;
57         }
58     }
59 }

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/11830191.html