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

链表分割

文章目录

  • 链表分割
    • 一、题目
    • 二、思路分析

一、题目

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

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


二、思路分析

错误思路:

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


普通思路:

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

【NowCoder.链表.CM11】链表分割,思路分析+图解_第1张图片

结果:

【NowCoder.链表.CM11】链表分割,思路分析+图解_第2张图片

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

我们任然需要切换思路


巧妙思路:

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

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

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

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

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

【NowCoder.链表.CM11】链表分割,思路分析+图解_第3张图片

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

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

x = 3为例

模拟第一步:

【NowCoder.链表.CM11】链表分割,思路分析+图解_第4张图片

模拟第二步:

【NowCoder.链表.CM11】链表分割,思路分析+图解_第5张图片

模拟第三步

【NowCoder.链表.CM11】链表分割,思路分析+图解_第6张图片

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

模拟第四步

【NowCoder.链表.CM11】链表分割,思路分析+图解_第7张图片

模拟第五步

【NowCoder.链表.CM11】链表分割,思路分析+图解_第8张图片

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

最后变成:

【NowCoder.链表.CM11】链表分割,思路分析+图解_第9张图片

代码如下:

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

你可能感兴趣的:(Practice,makes,perfect.,链表,数据结构,c语言,c++)