AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

5.链表(奇偶)

作者: 作者的头像   有点丶 ,  2022-09-24 17:06:03 ,  所有人可见 ,  阅读 278


0


1.将一个带头节点的单链表分解为两个带头节点的单链表A,B,使得A表中含有
原表中序号为奇数的元素,B表中含有偶数的元素.且相对顺序不变

思路
1.申请一个变量,确定奇偶
2.将偶数序号的摘下来尾插到链表B,奇数序号的拆下来尾插到链表A
代码

ListNode*splitAtoAB(ListNode*A)
{
    ListNode*B=new ListNode(-1);
    B->next=NULL;

    ListNode*tailA=A;      //A的尾指针
    ListNode*cur=A->next;//工作循环的遍历指针

    ListNode*tailB=B;    //B的尾指针

    int os=1;   
    while(cur)
    {
        if(os%2==1)
        {
            tailA->next=cur;
            tailA=tailA->next; 
        }   
        else
        {
            tailB->next=cur;
            tailB=tailB->next; 
        }
        cur=cur->next;
        os++;
    } 
    tailA->next=NULL;
    tailB->next=NULL;
    return B;
}

2.将C={a1,b1,a2,b2,…,an,bn},采用带头节点的hc单链表存放,设计一个就地算法,将其拆分
为两个线性表,使得A={a1,a2,…,an},B={bn,…,b2,b1}

思路
1.申请一个变量,确定奇偶
2.将偶数序号的摘下来头插到链表B,奇数序号的拆下来尾插到链表A

ListNode*splitAtoAB(ListNode*c)
{
    ListNode*A=new ListNode(-1);
    ListNode*B=new ListNode(-1);

    ListNode*tailA=A;   //A的尾节点  

    A->next=NULL;
    B->next=NULL;

    int os=1;
    ListNode*cur=c->next;

    while(cur)
    {
        ListNode*ne=cur->next;
        //尾插入A 
        if(os%2==1)
        {
            tailA->next=cur;
            tailA=tailA->next; 
        }
        //头插入B 
        else
        {
            //cur的next会变,事先存下来 
            cur->next=B->next;
            B->next=cur; 
        }
        cur=ne;
        os++;
    }

     tailA->next=NULL;
     return A;
}

3.奇偶链表
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。

第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。

请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。

你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

输入: head = [1,2,3,4,5]
输出: [1,3,5,2,4]

输入: head = [2,1,3,5,6,4,7]
输出: [2,3,6,7,1,5,4]

时间复杂度:
遍历时将位置编号是奇数的节点插在奇数链表尾节点后面,将位置编号是偶数的节点插在偶数链表尾节点后面。

遍历完整个链表后,将偶数链表头结点插在奇数链表尾节点后面即可。
整个链表只遍历一次,所以时间复杂度是 O(n)O,遍历时只记录了常数个额外的指针,所以额外的空间复杂度是 O(1)。

代码

class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if (!head || !head->next) return head;
        ListNode*odd=head;
        ListNode*even=head->next;
        ListNode*_even=head->next;
        for(auto p=head->next->next;p;)
        {
            odd->next=p;
            odd=odd->next;
            p=p->next;
            if(p)
            {
                even->next=p;
                even=even->next;
                p=p->next;
            }
        }
        odd->next=_even;
        even->next=NULL;
        return head;
    }
};

4. 分割链表
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你不需要 保留 每个分区中各节点的初始相对位置。

代码

//分出小于x的组成一个链表,大于等于的组成另一个连边,并且保留了相对位置
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode*small=new ListNode(-1);
        ListNode*big=new ListNode(-1);
        ListNode*_ebig=big;
        ListNode*_esmall=small;
        ListNode*cur=head;
        while(cur)
        {
            if(cur->val<x)
            {
                small->next=cur;
                small=small->next;
            }
            else
            {
                big->next=cur;
                big=big->next;
            }
            cur=cur->next;
        }
        small->next=_ebig->next;
        big->next=NULL;
        return _esmall->next;

    }
};

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息