您的位置:首页 > 其它

LeetCode - Reorder List

2014-01-13 22:17 387 查看
Reorder List

2014.1.13 22:07

Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

For example,
Given
{1,2,3,4}
, reorder it to
{1,4,2,3}
.

Solution1:

  My solution for this problem is in three steps:

    1. cut the list in two halves of equal length (maybe differ by 1).

    2. reverse the latter one.

    3. merge them in a crossing manner: 1->2->1->2->1->...

  Time complexity is O(n), space complexity is O(1), where n is the number of nodes in the list.

Accepted code:

// 4CE, 1AC, if you're able to design the right algorithm with just one shot, why failed by 4 foolish CEs?
/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void reorderList(ListNode *head) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(head == nullptr){
// 1CE here, void function...
return;
}

int n, n1, n2;
// 1CE here, ListNode, not List...
ListNode *h1, *h2, *ptr;

h1 = head;
ptr = head;
n = 0;
while(ptr != nullptr){
++n;
ptr = ptr->next;
}
n1 = (n + 1) / 2;
n2 = n - n1;
ptr = head;
// 1CE here, declaration for $i missing
for(int i = 1; i < n1; ++i){
ptr = ptr->next;
}
h2 = ptr->next;
ptr->next = nullptr;
h2 = reverseList(h2);

ListNode *root = new ListNode(0), *tail;
ListNode *p1, *p2;
tail = root;
while(h1 != nullptr || h2 != nullptr){
if(h1 != nullptr){
tail->next = h1;
h1 = h1->next;
tail = tail->next;
tail->next = nullptr;
}
if(h2 != nullptr){
tail->next = h2;
h2 = h2->next;
tail = tail->next;
tail->next = nullptr;
}
}

head = root->next;
delete root;
// 1CE here, void function has no return
}
private:
ListNode *reverseList(ListNode *head) {
if(nullptr == head){
return head;
}

ListNode *ptr1, *ptr2, *root;

root = new ListNode(0);
ptr1 = head;
while(ptr1 != nullptr){
ptr2 = root->next;
root->next = ptr1;
ptr1 = ptr1->next;
root->next->next = ptr2;
}

head = root->next;
delete root;
return head;
}
};


Solution2:

  I've noticed that I used an extra new operation in the code. This overhead can be avoided.

Accepted code:

// 2WA, 1AC, not so satisfactory
class Solution {
public:
void reorderList(ListNode *head) {
if(head == nullptr){
return;
}

int n, n1, n2;
ListNode *h1, *h2, *ptr;

h1 = head;
ptr = head;
n = 0;
while(ptr != nullptr){
++n;
ptr = ptr->next;
}
n1 = (n + 1) / 2;
n2 = n - n1;
ptr = head;
for(int i = 1; i < n1; ++i){
ptr = ptr->next;
}
h2 = ptr->next;
ptr->next = nullptr;
h2 = reverseList(h2);

ListNode *tail;
ListNode *p1, *p2;
tail = nullptr;
head = h1;
while(h1 != nullptr || h2 != nullptr){
if(h1 != nullptr){
if(tail != nullptr){
tail->next = h1;
tail = tail->next;
}else{
tail = h1;
}
h1 = h1->next;
tail->next = nullptr;
}
if(h2 != nullptr){
if(tail != nullptr){
tail->next = h2;
tail = tail->next;
}else{
tail = h2;
}
h2 = h2->next;
tail->next = nullptr;
}
}
}
private:
ListNode *reverseList(ListNode *head) {
if(nullptr == head){
return head;
}

ListNode *ptr1, *ptr2;

ptr1 = head;
head = nullptr;
while(ptr1 != nullptr){
ptr2 = ptr1;
ptr1 = ptr1->next;
if(head != nullptr){
// 2WA here, better manually debug it before submission
ptr2->next = head;
head = ptr2;
}else{
head = ptr2;
ptr2->next = nullptr;
}
}

return head;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: