143. 重排链表
最后更新:2023-12-02
链接:https://leetcode.cn/problems/reorder-list/description/
题目描述
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
\(L0 → L1 → … → Ln - 1 → Ln\)
请将其重新排列后变为:
\(L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …\)
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
题目示例

输入: head = [1,2,3,4]
输出: [1,4,2,3]

输入: head = [1,2,3,4,5]
输出: [1,5,2,4,3]
提示:
- 链表的长度范围为 \([1, 5 * 10^4]\)
- \(1 <= node.val <= 1000\)
C |
---|
| #define INSERT_LIST_NEXT(list, node) \
(list)->next = node;\
(node) = (node)->next;\
(list) = (list)->next;
#define INSERT_LIST(list, node) \
(list)->next = node;\
(list) = (list)->next;\
(list)->next = NULL;
int List_Length(struct ListNode* head)
{
int len = 0;
struct ListNode* temp = head;
while (temp != NULL) {
temp = temp->next;
len++;
}
return len;
}
// 按照步长拆分链表为两个
void List_SpiltByStep(struct ListNode* head, struct ListNode* list1, struct ListNode* list2, int step)
{
struct ListNode* temp = head;
bool flag = false;
int count = 0;
while (temp != NULL) {
struct ListNode* next = temp->next;
if (flag == false) {
INSERT_LIST(list1, temp);
count++;
} else {
INSERT_LIST(list2, temp);
count++;
}
if (count == step) {
flag = !flag;
count = 0;
}
temp = next;
}
}
struct ListNode* List_Inverted(struct ListNode* head)
{
struct ListNode invert = {0,NULL};
struct ListNode* temp = head;
while (temp != NULL) {
struct ListNode* next = temp->next;
temp->next = invert.next;
invert.next = temp;
temp = next;
}
return invert.next;
}
struct ListNode* List_Merged(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode head = {0,NULL};
struct ListNode *temp = &head;
// 遍历,插入
while ((list1 != NULL) && (list2 != NULL)) {
INSERT_LIST_NEXT(temp, list1);
INSERT_LIST_NEXT(temp, list2);
}
// 插入l1。L2为空
while (list1 != NULL) {
INSERT_LIST_NEXT(temp, list1);
}
// 插入l2,l1为空
while (list2 != NULL) {
INSERT_LIST_NEXT(temp, list2);
}
return head.next;
}
void reorderList(struct ListNode* head)
{
struct ListNode list1 = {0,NULL};
struct ListNode list2 = {0,NULL};
// 第一步,计算链表长度
int len = List_Length(head);
// 第二步,拆分成两个链表,list1,list2,步长n/2
List_SpiltByStep(head, &list1, &list2, (len + 1) / 2);
// 第三步, 翻转list2
list2.next = List_Inverted(list2.next);
// 第四步,合并list1和list2
head = List_Merged(list1.next, list2.next);
}
|
C |
---|
| #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uthash.h"
#define INSERT_LIST_NEXT(list, node) \
(list)->next = node;\
(node) = (node)->next;\
(list) = (list)->next;
#define INSERT_LIST(list, node) \
(list)->next = node;\
(list) = (list)->next;\
(list)->next = NULL;
// 从链表中间拆分为两个两边
void List_SpiltMiddle(struct ListNode* head, struct ListNode** list1, struct ListNode** list2)
{
struct ListNode* slow = head;
struct ListNode* fast = head;
struct ListNode* tail = NULL;
while ((slow != NULL) && (fast->next != NULL)) {
tail = slow;
slow = slow->next;
fast = fast->next->next;
if (fast == NULL) {
break;
}
}
*list1 = head;
tail->next = NULL;
*list2 = slow;
}
struct ListNode* List_Inverted(struct ListNode* head)
{
struct ListNode invert = {0,NULL};
struct ListNode* temp = head;
while (temp != NULL) {
struct ListNode* next = temp->next;
temp->next = invert.next;
invert.next = temp;
temp = next;
}
return invert.next;
}
struct ListNode* List_Merged(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode head = {0,NULL};
struct ListNode *temp = &head;
// 遍历,插入
while ((list1 != NULL) && (list2 != NULL)) {
INSERT_LIST_NEXT(temp, list1);
INSERT_LIST_NEXT(temp, list2);
}
// 插入l1。L2为空
while (list1 != NULL) {
INSERT_LIST_NEXT(temp, list1);
}
// 插入l2,l1为空
while (list2 != NULL) {
INSERT_LIST_NEXT(temp, list2);
}
return head.next;
}
void reorderList(struct ListNode* head)
{
struct ListNode *list1 = NULL;
struct ListNode *list2 = NULL;
if ((head == NULL) || (head->next == NULL)){
return head;
}
// 第一步,拆分成两个链表,list1,list2
List_SpiltMiddle(head, &list1, &list2);
// 第二步, 翻转list2
list2 = List_Inverted(list2);
// 第三步,合并list1和list2
head = List_Merged(list1, list2);
}
|
C |
---|
| void reorderList(struct ListNode* head) {
if (head == NULL) {
return;
}
struct ListNode* vec[40001];
struct ListNode* node = head;
int n = 0;
while (node != NULL) {
vec[n++] = node;
node = node->next;
}
int i = 0, j = n - 1;
while (i < j) {
vec[i]->next = vec[j];
i++;
if (i == j) {
break;
}
vec[j]->next = vec[i];
j--;
}
vec[i]->next = NULL;
}
|
Go |
---|
| func reorderList(head *ListNode) {
if head == nil {
return
}
nodes := []*ListNode{}
for node := head; node != nil; node = node.Next {
nodes = append(nodes, node)
}
i, j := 0, len(nodes)-1
for i < j {
nodes[i].Next = nodes[j]
i++
if i == j {
break
}
nodes[j].Next = nodes[i]
j--
}
nodes[i].Next = nil
}
|
C++ |
---|
| class Solution {
public:
void reorderList(ListNode *head) {
if (head == nullptr) {
return;
}
vector<ListNode *> vec;
ListNode *node = head;
while (node != nullptr) {
vec.emplace_back(node);
node = node->next;
}
int i = 0, j = vec.size() - 1;
while (i < j) {
vec[i]->next = vec[j];
i++;
if (i == j) {
break;
}
vec[j]->next = vec[i];
j--;
}
vec[i]->next = nullptr;
}
};
|
Python |
---|
| class Solution:
def reorderList(self, head: ListNode) -> None:
if not head:
return
vec = list()
node = head
while node:
vec.append(node)
node = node.next
i, j = 0, len(vec) - 1
while i < j:
vec[i].next = vec[j]
i += 1
if i == j:
break
vec[j].next = vec[i]
j -= 1
vec[i].next = None
|