【链表OJ题 5】牛客 CM11 链表分割

文章详细介绍了如何使用C++实现链表分割的两种方法,一种是使用哨兵位的头结点,另一种是不带哨兵位的头结点。代码实现中涉及到了链表的尾插法和头结点的更新,同时注意处理可能的环形链表情况。最后给出了两种方法的思路分析和易错点提示。
摘要由CSDN通过智能技术生成

目录

题目来源:

代码实现:

1.带哨兵位的头结点

2.不带哨兵位的头结点

思路分析:

1.带哨兵位的头结点

实现过程:

易错点:

2.不带哨兵位的头结点

实现过程:

易错点:


题目来源:

链表分割_牛客题霸_牛客网 (nowcoder.com)

题目描述:

代码实现:

1.带哨兵位的头结点

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        struct ListNode* lesshead = NULL, * lesstail = NULL, * greaterhead = NULL,
            * greatertail = NULL, * cur = pHead;
        lesshead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode));
        greaterhead = greatertail = (struct ListNode*)malloc(sizeof(struct ListNode));

        while (cur)
        {
            //尾插
            if (cur->val < x)
            {
                lesstail->next = cur;
                lesstail = lesstail->next;
            }
            else
            {
                greatertail->next = cur;
                greatertail = greatertail->next;
            }
            //迭代
            cur = cur->next;
        }

        //连接
        lesstail->next = greaterhead->next;
        //置空大头尾结点的next
        greatertail->next = NULL;
        //将新的头结点指针赋给原头结点指针
        pHead = lesshead->next;
        //释放大小头结点并置空
        free(lesshead);
        lesshead = NULL;
        free(greaterhead);
        greaterhead = NULL;

        return pHead;
    }
};

2.不带哨兵位的头结点

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        struct ListNode* lesshead = NULL, * lesstail = NULL, * greaterhead = NULL,
            * greatertail = NULL;

        while (pHead)
        {
            //尾插
            if (pHead->val < x)
            {
                if(NULL == lesstail)
                {
                    lesshead = lesstail = pHead;
                }                    
                else
                {
                    lesstail->next = pHead;
                    lesstail = lesstail->next; 
                }
            }
            else
            {
                if(NULL == greatertail)
                {
                    greaterhead = greatertail = pHead;
                }                    
                else
                {
                    greatertail->next = pHead;
                    greatertail = greatertail->next; 
                }
            }
            //迭代
            pHead = pHead->next;
        }

        //小头为空
        if(lesshead != NULL && greaterhead == NULL)
        {
            lesstail = NULL;
            return lesshead;
        }
        //大头为空
        if(lesshead == NULL && greaterhead != NULL)
        {
            greatertail = NULL;
            return greaterhead;
        }
        //连接
        lesstail->next = greaterhead;
        //置空大头尾结点的next
        greatertail->next = NULL;

        return lesshead;
    }
};

思路分析:

1.带哨兵位的头结点

为实现本题,我们先将原链表头结点赋给cur,再开辟两个结构体,并将其分别赋给结构体指针变量,lesshead = lesstail,greaterhead = greatertail。小于 x 尾插在 lesstail->next 上,大于 x 尾插在 greatertail->next 上。

实现过程:

1.创建两个带哨兵位的新链表,分别存放小于 x 的所有结点和大于 x 的所有结点。我们定义小于 x 的头尾结点为lesshead,lesstail;定义大于 x 的头尾结点为 greaterhead,greatertail。

2.遍历链表,val < x 那么就尾插在 lesstail->next,val > x 那么就尾插在 greatertail->next。然后更新原链表的头结点和插入后的尾指针,分别都往后走一步。

3.循环步骤2,遍历完整个原链表,这时也就将大小分开了,再将 lesstail->next = greaterhead->next 并将greatertail->next = NULL,再将新的头结点赋值给原链表头,pHead = lesshead->next(因为最后要释放掉lesshead与greaterhead,并置空,所以要将小头结点赋值给pHead)。

4.释放 lesshead,greaterhead,并返回 pHead。

易错点:

可能会出现环形链表:

为了避免这种情况的发生,我们最后将 greatertail->next = NULL 处理,这样就避免了这种情况。

2.不带哨兵位的头结点

主要的思路是一致的,只是这次我们不开辟结构体,直接定义结构体指针lesshead、lesstail,greaterhead、greatertail,并将其置空。

实现过程:

与带哨兵位的头结点实现过程类似,不同点:

1.连接那块,lesstail->next = greaterhead,因为这次没有哨兵位,不用连接next。

2.返回值lesshead不是动态开辟的,不用释放,因此就不用再赋回去,直接返回 lesshead。

易错点:

1> 可能会出现环形链表:

为了避免这种情况的发生,我们最后将 greatertail->next = NULL 处理,这样就避免了这种情况。

2> 将大小分开后 lesshead或者greaterhead 可能为空,需要判断:

//小头为空
if(lesshead != NULL && greaterhead == NULL)
{
    lesstail = NULL;
    return lesshead;
}
//大头为空
if(lesshead == NULL && greaterhead != NULL)
{
    greatertail = NULL;
    return greaterhead;
}

如果大牛的您看到有什么问题留言给我,我一定会认真看的,谢谢您。如果您看了觉得有收获,关注 + 点赞支持一下呗。

*** 本篇结束 ***

  • 24
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白在努力jy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值