-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
129 lines (113 loc) · 3.08 KB
/
main.cpp
File metadata and controls
129 lines (113 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Source: https://leetcode.com/problems/reorder-list
// Title: Reorder List
// Difficulty: Medium
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// You are given the head of a singly linked-list. The list can be represented as:
//
// ```
// L_0 → L_1 → … → L_n - 1 → L_n
// ```
//
// Reorder the list to be on the following form:
//
// ```
// L_0 → L_n → L_1 → L_n - 1 → L_2 → L_n - 2 → …
// ```
//
// You may not modify the values in the list's nodes. Only nodes themselves may be changed.
//
// **Example 1:**
// https://assets.leetcode.com/uploads/2021/03/04/reorder1linked-list.jpg
//
// ```
// Input: head = [1,2,3,4]
// Output: [1,4,2,3]
// ```
//
// **Example 2:**
// https://assets.leetcode.com/uploads/2021/03/09/reorder2-linked-list.jpg
//
// ```
// Input: head = [1,2,3,4,5]
// Output: [1,5,2,4,3]
// ```
//
// **Constraints:**
//
// - The number of nodes in the list is in the range `[1, 5 * 10^4]`.
// - `1 <= Node.val <= 1000`
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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 {
private:
// Find middle node
// [] -> null
// [1] -> 1
// [1, 2] -> 1
// [1, 2, 3] -> 2
// [1, 2, 3, 4] -> 2
ListNode* getMiddle(ListNode* head) {
if (head == nullptr) return nullptr;
ListNode* slow = head;
ListNode* fast = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
// Reverse List
// [] -> []
// [1] -> [1]
// [1, 2, 3] -> [3, 2, 1]
ListNode* reverseList(ListNode* head) {
ListNode* reverseHead = nullptr;
auto node = head;
while (node != nullptr) {
auto currNode = node;
node = node->next;
// Push at front of reversed list
currNode->next = reverseHead;
reverseHead = currNode;
}
return reverseHead;
}
// Merge both list alternatively.
// The new head is left head.
void mergeLists(ListNode* left, ListNode* right) {
ListNode dummy;
auto node = &dummy;
while (left != nullptr && right != nullptr) {
// Insert left
node->next = left;
left = left->next;
node = node->next;
// Insert right
node->next = right;
right = right->next;
node = node->next;
}
// Insert remaining nodes
node->next = (left != nullptr) ? left : right;
}
public:
void reorderList(ListNode* head) {
// Edge case, ensure midNode is not null
if (head == nullptr) return;
// Find middle node (end of left half)
auto midNode = getMiddle(head);
// Reverse right half
auto rightHead = reverseList(midNode->next);
midNode->next = nullptr; // disconnect end of left half
// Merge both lists
mergeLists(head, rightHead);
}
};