LeetCode 328. Odd Even Linked List(奇偶链表) -- C语言

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;
}

后记:

需多加注意指针的情况,设置好指针条件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值