您的位置:首页 > 其它

]Leetcode]-[Reorder List ]-三种解法

2015-03-13 21:58 344 查看
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}
.

题目的意思就是,给定一个链表,从两头开始链接,

比如1-2-3-4-5-6,最开始取两头,组成1-6,剩下2-3-4-5;

接着取两头,2-5,和上面的1-6连接起来,组成1-6-2-5,剩下3-4;

接着取两头, 3-4,同理和上面的结果连接起来,组成 1-6-2-5-3-4;

我一共做了3种解法:第一种解法,使用递归的解法,每次都取两头,然后递归的去解;一共递归n/2次,每次需要从头开始遍历到最后一个元素,需要n步,所以时间复杂度是O(N*N),, 空间复杂度O(1). 但是结果是超时了。。。

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:

ListNode *recurse(ListNode *head)
{
if(head == NULL || head->next == NULL)
{
return head;
}
ListNode *cur = head, *pre = head;
while(cur->next != NULL)
{
pre = cur;
cur = cur->next;
}
pre->next = NULL;
ListNode *next = head->next;
head->next = cur;
cur->next = recurse(next);
return head;
}
void reorderList(ListNode *head)
{
if(head == NULL || head->next == NULL)
return;
head =recurse(head);

}
};


第二种解法,比较有效率,O(N)的时间复杂度,O(1)空间复杂度。思路是:将链表平均分为前后2段(l和r),将r倒转,然后按照顺序将l和r拼接起来。AC了

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:

ListNode *split(ListNode *head)
{
ListNode *p = head;
ListNode *q = head->next;
while(q != NULL && q->next != NULL)
{
q = q->next->next;
p = p->next;
}
q = p->next;
p->next = NULL;
return q;
}

ListNode *reverse(ListNode *head)
{
if(head == NULL || head->next == NULL)
return head;
ListNode *pre = head, *cur = head->next, *next;
head->next = NULL;
while(cur != NULL)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
void reorderList(ListNode *head)
{
if(head == NULL || head->next == NULL)
return;
ListNode *r = reverse(split(head));
ListNode *l = head->next;
ListNode *traverse = head;
while(r != NULL && l != NULL)
{
ListNode *tmp_r = r->next;
ListNode *tmp_l = l->next;
traverse->next = r;
traverse = traverse->next;
traverse->next = l;
traverse = traverse->next;
l = tmp_l;
r = tmp_r;
}
if(r != NULL)
traverse->next = r;
else
traverse->next = l;
}
};


最后一种解法是最直接的,借助了一个O(N)的空间,写起来比较简单,而且代码很容易懂,依然O(N)的时间复杂度,比第二种解法快了3ms。

/**
* 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)
{
if(head == NULL || head->next == NULL)
return;
vector<ListNode *> vec;
ListNode *p = head->next;
while(p != NULL)
{
vec.push_back(p);
p = p->next;
}
p = head;
vector<ListNode *>::size_type i, j;
for(i = 0, j = vec.size() - 1; i < j; i++, j--)
{
p->next = vec[j];
p = p->next;
p->next = vec[i];
p = p->next;
}
if(i == j)
{
p->next = vec[i];
p = p->next;
}
p->next = NULL;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: