---
# System prepended metadata

title: '[143. Reorder List](https://leetcode.com/problems/reorder-list/)'
tags: [leetcode]

---

---
tags: leetcode
---

# [143. Reorder List](https://leetcode.com/problems/reorder-list/)
---
# My Solution
## The Key Idea for Solving This Coding Question
如何以交叉編織的方式合併兩個單向鏈結串列 (第 38 ~ 53 行)
1. 假設 `head` 指向的單向鏈結串列長度==小於或等於== `head2` 指向的單向鏈結串列。
2.  因為 `it1->next` 與 `it2->next` 皆必須改變所要指向的節點，所以先分別以 `tmp1` 與 `tmp2` 紀錄 `it1->next` 與 `it2->next` 目前所指向的節點。
3. 依題意將 `it1->next` 與 `it2->next` 指向應指向的節點。
    * `it1->next` 指向 `it2`。
    * `it1` 走到 `tmp1` 所在節點 (也就是 `it1->next` 原本指向的節點)。
    * 因為 `head` 指向的單向鏈結串列長度小於或等於 `head2` 指向的單向鏈結串列，所以要先檢查 `it1` 是否為 `nullptr` 。若 `it1` 為 `nullptr` ，表示合併結束，離開 `while` 迴圈。否則，繼續合併。
    * `it2->next` 指向 `it1` 。
    * `it2` 走到 `tmp2` 所在節點 (也就是 `it2->next` 原本指向的節點)。
4. 重複步驟 2 與 3 。
## C++ Code
```cpp=
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */

class Solution {
public:
    void reorderList(ListNode *head) {
        if (head == nullptr || head->next == nullptr) {
            return;
        }

        ListNode *preSlow = nullptr, *slow = head, *fast = head;
        while (fast != nullptr && fast->next != nullptr) {
            preSlow = slow;
            slow = slow->next;
            fast = fast->next->next;
        }

        // Break the list.
        preSlow->next = nullptr;

        // Reverse the second half of the list.
        ListNode *head2 = nullptr;
        while (slow != nullptr) {
            ListNode *tmp = slow->next;
            slow->next = head2;
            head2 = slow;
            slow = tmp;
        }

        // Interweave the two lists.
        ListNode *it1 = head, *it2 = head2;
        while (true) {
            ListNode *tmp1 = it1->next;
            ListNode *tmp2 = it2->next;
            it1->next = it2;
            it1 = tmp1;
            if (it1 == nullptr) {
                // Because the list length of it1 is shorter 
                // than or equal to that of it2, it1 reaches
                // the end of its list first.
                break;
            }
            it2->next = it1;
            it2 = tmp2;
        }
    }
};
```
## Time Complexity
$O(n)$
$n$ is the total number of nodes in the linked list.
## Space Complexity
$O(1)$
# Miscellaneous
<!--
# Test Cases
```
[1,2,3,4]
```
```
[1,2,3,4,5]
```
```
[1]
```
```
[1,2]
```
```
[1,2,3]
```
-->