143. Reorder List
一、题目分析

要求不能采用复制的手段,不能使用多余的空间
解析:
可以看出规律,最后的结果是将链表右边的部分逆转之后,和左边的部分穿插合并得来:
二、代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//逆转链表,head是下部分的链表头,last是上一个节点。
ListNode* reverseList(ListNode* head, ListNode* last)
{
if(head)
{
ListNode* next = head->next;
head->next = last;
return this->reverseList(next, head);
}
return last;
}
int lengthOfList(ListNode* head)
{
int length = 0;
while (head) {
head = head->next;
length++;
}
return length;
}
// https://leetcode.com/problems/reorder-list/description/
void reorderList(ListNode* head) {
int length = this->lengthOfList(head);
ListNode *right = head;
int index = length/2 - 1;
//寻找中间节点
while (right && index > 0) {
right = right->next;
index--;
}
//逆转右边的部分
if(right)
{
ListNode *rightHead = right->next;
right->next = NULL;
right = this->reverseList(rightHead, NULL);
}
//test
// this->dump(head);
// this->dump(right);
// this->dump(this->merge_list(head, right));
this->merge_list(head, right);
}
ListNode* merge_list(ListNode* left, ListNode *right)
{
ListNode *p = new ListNode(-1);
ListNode *head = p;
while (left && right) {
p->next = left;
left = left->next;
p = p->next;
p->next = right;
right = right->next;
p = p->next;
}
while (left) {
p->next = left;
left = left->next;
p = p->next;
}
while (right) {
p->next = right;
right = right->next;
p = p->next;
}
return head->next;
}
};

浙公网安备 33010602011771号