【牛客CM11】链表分割

刷爆LeetCode系列

牛客CM11:

github地址

有梦想的电信狗

前言

本文用C++实现牛客CM11


题目描述

题目链接https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking


题目与思路分析

目标分析

  1. 编写代码,给定链表的头指针 pHead以给定值x为基准 ,将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前

  2. 不能改变原来数据的顺序

  3. 返回 分割后的新链表的头指针

  4. 要求 :时间复杂度为O(n),空间复杂度为O(1)

思路 :创建两个哨兵位的头结点 guardLessguardGreater,遍历链表,小于 x 的结点尾插guardLess,大于 x 的结点尾插guardGreater,最终再将两个链表连接起来,尾插的时候注意记录tail结点

操作

  • 空链表检查if (pHead == nullptr) return nullptr;

  • 创建两个哨兵位的头结点

cpp 复制代码
ListNode* guardLess = new ListNode(-1);
ListNode* guardGreater = new ListNode(-1);
  • 分别创建两个链表的尾结点,方便尾插时无需频繁找尾
cpp 复制代码
ListNode* lessTail = guardLess, *greaterTail = guardGreater
  • curNode为移动指针,用于遍历链表

    • 小于 x 的结点尾插到 guardLess 链表中,同时尾指针 lessTail 向后移动
    • 大于等于 x 的结点尾插到 guardGreater 链表中,同时尾指针 greaterTail 向后移动
    • 每次循环中curNode指针向后移动curNode = curNode->next
  • 连接两个新链表lessTail->next = guardGreater->next

  • 最后一个结点的 next 指针需要置空,防止链表带环greaterTail->next = nullptr

  • 保存新链表的头结点pHead = guardLess->next

  • 释放手动开辟的哨兵位头结点

cpp 复制代码
  delete guardGreater;
  delete guardLess;
  • 最终返回新链表的头结点return pHead

代码实现

cpp 复制代码
class Partition {
  public:
    ListNode* partition(ListNode* pHead, int x) {
        if (pHead == nullptr)
            return nullptr;
        ListNode* guardLess = new ListNode(-1);
        ListNode* guardGreater = new ListNode(-1);

        ListNode* lessTail = guardLess, *greaterTail = guardGreater;
        ListNode* curNode = pHead;
        while (curNode) {
            if (curNode->val < x) {
                lessTail->next = curNode;
                lessTail = lessTail->next;
            }
            else{
                greaterTail->next = curNode;
                greaterTail = greaterTail->next;
            }
            curNode = curNode->next;
        }
        // 链接两个链表
        lessTail->next = guardGreater->next;
        
        // 最后一个结点的 next 指针需要置空,防止链表带环
        greaterTail->next = nullptr;    
		// 释放哨兵位的头结点
        pHead = guardLess->next;
        delete guardGreater;
        delete guardLess;

        return pHead;
    }
};

算法代码优化

  • 以上代码和思路已足够精简,无需优化

以上就是本文的所有内容了,如果觉得文章对你有帮助,欢迎 点赞⭐收藏 支持!如有疑问或建议,请在评论区留言交流,我们一起进步

分享到此结束啦
一键三连,好运连连!

你的每一次互动,都是对作者最大的鼓励!


征程尚未结束,让我们在广阔的世界里继续前行! 🚀

相关推荐
艾莉丝努力练剑1 分钟前
【Linux网络】Linux 网络编程:HTTP(三)HTTP 协议原理
linux·运维·服务器·网络·c++·http
Gauss松鼠会2 分钟前
GaussDB(DWS) 资源监控Topsql
java·网络·数据库·算法·oracle·性能优化·gaussdb
夏日听雨眠3 分钟前
数据结构(快速排序)
java·数据结构·算法
薇茗4 分钟前
【初阶数据结构】 升沉有序的平仄 排序 3
c语言·开发语言·数据结构·算法·排序算法·文件归并排序
字节高级特工6 分钟前
C++11(一) 革新:右值引用与移动语义
java·开发语言·c++·人工智能·后端
孬甭_6 分钟前
双向链表详解
c语言·数据结构·链表
薇茗6 分钟前
【初阶数据结构】 升沉有序的平仄 排序 2
c语言·数据结构·算法·排序算法·快排精讲
安生生申8 分钟前
uni-app 连接 JDY-31 蓝牙串口模块实践
c语言·前端·javascript·stm32·单片机·嵌入式硬件·uni-app
叶之香9 分钟前
一次 Kingston U 盘重定向中获取 Device Descriptor 超时问题排查
c++·windows·visual studio
UestcXiye9 分钟前
GoogleTest 使用指南 | 单元覆盖率分析
c++·单元测试·googletest