Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→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.
先对半拆分链表,逆序后面的链表,然后merge成一个链表.
为了便于复习,我把三种链表反转的函数都列出来了.
链表反转见LeetCode:206. Reverse Linked List.我整理的相应的解答
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**************************************************************************
*
* 143. [Reorder List](https://leetcode.com/problems/reorder-list/)
*
* You are given the head of a singly linked-list. The list can be represented as:
* L0 → L1 → … → Ln - 1 → Ln
* Reorder the list to be on the following form:
*
* L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
*
* You may not modify the values in the list's nodes. Only nodes themselves may be changed.
*
* Example 1:
* Input: head = [1,2,3,4]
* Output: [1,4,2,3]
*
* Example 2:
* Input: head = [1,2,3,4,5]
* Output: [1,5,2,4,3]
**************************************************************************/
struct ListNode {
int val;
struct ListNode *next;
};
typedef struct ListNode NODE;
int lenOfList(NODE *head) {
int len = 0;
while (head) {
len++;
head = head->next;
}
return len;
}
NODE *reverseList(NODE *head) {
if (NULL == head || NULL == head->next)
return head;
NODE *pre = NULL;
NODE *cur = head;
NODE *next= cur->next;
while (cur) {
cur->next = pre;
pre = cur;
cur = next;
if (next)
next= next->next;
}
return pre;
}
NODE *reverse(NODE *head) {
if (NULL == head || NULL == head->next)
return head;
NODE *p = reverse(head->next);
head->next->next = head;
head->next = NULL;
return p;
}
// l1 head as head
NODE *merger(NODE *l1, NODE *l2) {
if (NULL == l1) return l2;
if (NULL == l2) return l1;
NODE *head = l1;
while (l1 && l2) {
NODE *l1_new = l1->next;
NODE *l2_new = l2->next;
l1->next = l2;
if (l1_new)
l2->next = l1_new;
l1 = l1_new;
l2 = l2_new;
}
return head;
}
void reorderList(NODE *head){
if (NULL == head || NULL == head->next || NULL == head->next->next)
return;
#if 1
/*******************************
* input 1 2 3 4 5
* l1 1 2
* l2 5 4 3 <-- 3 4 5 (l2)
*
* merger:
* 1 5 2 4 3
*******************************/
#ifdef FORCE
NODE *l1 = head;
NODE *l1tail = head;
NODE *l2 = head;
int len = lenOfList(head);
for (int i = 0; i < len / 2 - 1; i++)
l1tail = l1tail->next;
l2 = l1tail->next;
l1tail->next = NULL;
#else
NODE *l1 = head;
NODE *l2 = head;
NODE *fast = head;
NODE *prel2 = NULL;
while (fast && fast->next) {
prel2 = l2;
l2 = l2->next;
fast = fast->next->next;
}
prel2->next = NULL;
#endif
#else
/*******************************
* if reverse in this way
*
* input 1 2 3 4 5
* l1 1 3 5
* l2 4 2 <- 2 4 (l2)
*
* merger:
* 1 4 3 2 5
*******************************/
NODE *l1 = head;
NODE *l2 = head->next;
for (NODE *sl1 = l1; sl1; ) {
NODE *sl1_new = NULL;
NODE *sl2 = sl1->next;
if (sl2) {
sl1_new = sl2->next;
sl1->next = sl1_new;
if (sl1_new)
sl2->next = sl1_new->next;
}
sl1 = sl1_new;
}
#endif
l2 = reverseList(l2);
merger(l1, l2);
return;
}
//
//
/// testCode
void print(NODE *head) {
printf("len:%d ", lenOfList(head));
while (head) {
if (head->next)
printf("%d->", head->val);
else
printf("%d", head->val);
head = head->next;
}
printf("\n");
}
NODE *initList(int len, int val) {
if (len < 1) return NULL;
NODE *head = (NODE *)calloc(1, sizeof(NODE));
head->val = val;
NODE *pos = head;
for (int i = 1; i < len; i++) {
NODE *node = (NODE *)calloc(1, sizeof(NODE));
node->val = val + i;
pos->next = node;
pos = node;
}
return head;
}
int main() {
NODE *l1 = initList(4, 1);
NODE *l2 = initList(5, 5);
print(l1);
print(l2);
reorderList(l1);
reorderList(l2);
print(l1);
print(l2);
l1 = reverseList(l1);
l2 = reverseList(l2);
print(l1);
print(l2);
l1 = merger(l2, l1);
print(l1);
return 0;
}