【NowCoder.链表.CM11】链表分割,思路分析+图解

链表分割

一、题目

📝题目指路:CM11 链表分割_牛客题霸_牛客网 (nowcoder.com)

📖📖现有一链表的头指针ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针


二、思路分析

🎯错误思路:

遍历两遍链表,第一次找小的数,第二次找大的数,但存在隐患,因为链表是连在一起的,将前面节点放到新的链表中,链表中的结构会紊乱


🎯普通思路:

新定义一个哨兵的头节点,大于x的尾插,小于x的头插

在这里插入图片描述

结果:

在这里插入图片描述

可以看到方法是好方法,但是最后的结果顺序不对

我们任然需要切换思路


🎯巧妙思路:

✏️链表和数组不同,链表在链表的节点之间做手脚是不占用内存

✏️新建链表的节点去重新构建链表,只要把哨兵头节点free掉,就不存在占用空间

✏️既然要我们找比x小和比x大的数,分别放在两头,那么在第二种思路的基础上,我们不用同一个链表,因为可以看到中间的哨兵头节点还需要一个指针去存储它的地址

✏️而且我们需要的都是尾插,因为尾插顺序不会改变

✏️两个链表,一个存储比x小,一个存储比x大,最后再将链表链接起来

在这里插入图片描述

📏准备好需要的哨兵节点,以及尾插需要的双指针

📏因为这里不需要走回头路,直接插入就行,上面的next指针可以省略

📏x = 3为例

🌸模拟第一步:

在这里插入图片描述

🌸模拟第二步:

在这里插入图片描述

🌸模拟第三步

在这里插入图片描述

🌺🌺注意这里greaterhead和lesstail的下一个都指向4🌺🌺

🌸模拟第四步

在这里插入图片描述

🌸模拟第五步

在这里插入图片描述

🌺🌺这里最后greatertail还连着lesstail,所以最后要把它们next都为NULL🌺🌺

🌸🌸最后变成:

在这里插入图片描述

🌹🌹代码如下:

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        if(pHead == NULL)
        {
            return NULL;
        }
        
        ListNode* cur = pHead;
        ListNode* lesshead = (ListNode*)malloc(sizeof(ListNode));
        ListNode* greaterhead = (ListNode*)malloc(sizeof(ListNode));
        ListNode* lesstail = lesshead;
        ListNode* greatertail = greaterhead;
        
        while(cur)
        {
            if(cur->val < x)
            {
                lesstail->next = cur;
                lesstail = cur;
                cur = cur->next;
            }
            else
            {
                greatertail->next = cur;
                greatertail = cur;
                cur = cur->next;
            }
        }
        
        greatertail->next = NULL;
        lesstail->next = greaterhead->next;
        
        ListNode* ret = lesshead->next;
        free(greaterhead);
        free(lesshead);
        return ret;
    }
};

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

凛音Rinne

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

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

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

打赏作者

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

抵扣说明:

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

余额充值