一、题目分析
要求不能采用复制的手段,不能使用多余的空间
解析:
可以看出规律,最后的结果是将链表右边的部分逆转之后,和左边的部分穿插合并得来:
二、代码:
/** * 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; } };