Odd Even Linked List
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.
You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.
Example 1:
Input: 1->2->3->4->5->NULL
Output: 1->3->5->2->4->NULL
Example 2:
Input: 2->1->3->5->6->4->7->NULL
Output: 2->3->6->7->1->5->4->NULL
Note:
The relative order inside both the even and odd groups should remain as it was in the input.
The first node is considered odd, the second node even and so on …
解题思路
设置pre,p,r,三个指针。pre指向奇数区的最后一个结点,r指向偶数区的最后一个结点。p为工作指针,从第三个结点开始。通过指针的交换达到结点交换的目的
/**执行时间:8ms
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* oddEvenList(struct ListNode* head){
//链表结点≤2时直接返回。
if(head!=NULL&&head->next!=NULL){
struct ListNode* pre = head, *p = head->next->next,*r=head->next;
//pre指向奇数区的最后一个结点,r指向偶数区的最后一个结点。p为工作指针,从第三个结点开始。
while(p!=NULL){
r->next = p->next;
//将偶数结点添加到偶数区,同时也保存工作指针p的后继,避免未访问结点丢失
p->next =pre->next;
pre->next=p;
//将奇数结点添加到奇数区
pre=p;
//移动pre;将pre指向奇数区最后一个结点
if(r->next!=NULL){
//如果添加到偶数区的结点不为null,代表还有结点未访问,移动r到偶数区最后一个结点,并将p重新指向新的奇数结点
r=r->next;
p=r->next;
}
else break;//否,代表全部结点访问完毕
}//while
}
return head;
}
改进
//执行时间:8ms
struct ListNode* oddEvenList(struct ListNode* head) {
if(head == NULL || head->next == NULL || head->next->next == NULL){
//只有两个结点的情况直接返回
return head;
}
struct ListNode* odd = head;//偶数区最后一个
struct ListNode* even = odd->next;//奇数区最后一个
struct ListNode* p;
//注意:奇数区,偶数区,待插入区,三者是链接的,并未断开
while(even && even->next) {
//当偶数区最后一个even不为NULL,和待插入第一个结点even->!=NULL时代表还有结点需要插入
p = even->next;
//p指向待插入偶数结点
even->next = even->next->next;
//将偶数区与待插入区链接
p->next = odd->next;
odd->next = p;
odd = odd->next;
//插入节点。odd重新指向奇数区最后一个结点
even = even->next;
//插入结点。even重新指向偶数区最后一个结点
}
return head;
}
后记:
需多加注意指针的情况,设置好指针条件