奇偶链表
给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
示例 1:
输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
示例 2:
输入: 2->1->3->5->6->4->7->NULL
输出: 2->3->6->7->1->5->4->NULL
说明:
应当保持奇数节点和偶数节点的相对顺序。
链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。
思路:想起之前链接1中的方法,如下图。我们将其逆着来即可,将1个链表拆分成2个。
代码:
ListNode* oddEvenList(ListNode* head) {
if(!head || !head->next || !head->next->next) //数目为0,1,2直接返回原链表
return head;
ListNode* cur_node=head; //原链表的游标
ListNode* new_node=new ListNode(0); //新链表的表头
ListNode* cur_new=new_node; //新链表的游标
while(cur_node && cur_node->next && cur_node->next->next) //拆分链表
{
cur_new->next=cur_node->next;
cur_new=cur_new->next;
cur_node->next=cur_node->next->next;
cur_node=cur_node->next;
}
//将2个链表拼接,涉及到链表长度是奇数还是偶数,注意将尾部节点设置成NULL,否则形成环。最好自己分奇偶画示意图
if(!cur_node->next) //链表长度为奇数,当前表头的后节点为空
{
cur_new->next=NULL; //切断新链表与最后一个节点的连接,否则形成环状链表
}else //链表长度为偶数,当前表头的后节点不为空
{
cur_new->next=cur_node->next; //将新链表尾部与最后一个偶节点相连
cur_node->next=NULL; //切断原链表与最后一个偶节点的连接,否则形成环状链表
}
cur_node->next=new_node->next;
return head;
}
简化代码:
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
if(!head || !head->next || !head->next->next)
return head;
ListNode* cur_odd=head; //奇链表游标
ListNode* cur_even=cur_odd->next; //偶链表游标
ListNode* new_list=cur_even; //偶链表表头
while(cur_even && cur_even->next)
{
cur_odd->next=cur_even->next;
cur_odd=cur_odd->next;
cur_even->next=cur_odd->next;
cur_even=cur_even->next;
}
cur_odd->next=new_list; //奇链表尾部指向偶链表表头,此题因为必须要将两个表串联。
//在其他题中,如果没将尾部断开,容易形成环,造成死循环
return head;
}
};
结果:
简化后结果: