【面试经典 150 | 链表】分隔链表

文章目录

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更......
专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

【链表】【模拟】


题目来源

86. 分隔链表


解题思路

方法一:模拟

我们只需要维护两个链表 smalllarge 即可,前者用来按顺序存储所有小于 x 的节点,后者用来按顺序存储所有大于等于 x 的节点。

为了实现上述思路,我们分别定义了两个链表的两个指针,small 链表的头结点 sH、尾节点 sTlarge 链表的头结点 eAndgH、尾节点 eAndgT

从原链表的头结点 head 开始遍历,直至结束,记当前遍历的节点为 cur

  • 首先记录当前节点的下一个节点 next
  • 将当前的节点 cur 指向空节点;
  • 接着将 cur 的值与 x 进行比较:
    • 如果小于 x,则更新到 small 节点中,主要如果此时的 sH 为空,需要利用氮当前节点初始化 sH,否则直接将 cur 加在 sH 后面并更新 sT = cur
    • 类似的对于 cur->val >= x 的情况,也有类似操作
  • 最后更新 cur = next

最后,遍历完毕原链表后,将两段链表拼接起来。

返回答案时,如果 sT == nullptr,说明 small 链表为空,直接返回 large 链表的头结点 eAndgH 即可;否则返回 small 链表的头结点。

代码

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode* sH = nullptr, * sT = nullptr;
        ListNode* eAndgH = nullptr, * eAndgT = nullptr;
        ListNode* next = nullptr;
        
        while(head != nullptr) {    // 使用 head 作为当前的节点
            next = head->next;
            head->next = nullptr;

            if(head->val < x) {
                if(sH == nullptr) {
                    sH = head;
                    sT = head;
                }else {
                    sT->next = head;
                    sT = head;
                }
            }
            else {
                if(eAndgH == nullptr) {
                    eAndgH = head;
                    eAndgT = head;
                }else {
                    eAndgT->next = head;
                    eAndgT = head;
                }
            }
            head = next;
        }

        // 重新链接
        if(sT != nullptr) {
            sT->next = eAndgH;
        }
        return sT == nullptr ? eAndgH : sH;
    }
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n), n n n 为原链表的长度。

空间复杂度: O ( 1 ) O(1) O(1)。


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。

相关推荐
梁诚斌22 分钟前
使用OpenSSL接口读取pem编码格式文件中的证书
开发语言·c++
2301_803554525 小时前
c++中的绑定器
开发语言·c++·算法
海棠蚀omo5 小时前
C++笔记-位图和布隆过滤器
开发语言·c++·笔记
消失的旧时光-19435 小时前
c++ 的标准库 --- std::
c++·jni
小张成长计划..5 小时前
双向链表的实现
数据结构·链表
GiraKoo6 小时前
【GiraKoo】C++11的新特性
c++·后端
不午睡的探索者6 小时前
告别性能瓶颈!Python 量化工程师,进击 C++ 高性能量化交易的“必修课”!
c++·github
OpenC++6 小时前
【C++】观察者模式
c++·观察者模式·设计模式
老歌老听老掉牙6 小时前
粒子群优化算法实现与多维函数优化应用
c++·pso·粒子群算法
myloveasuka6 小时前
信号操作集函数
linux·运维·服务器·c语言·c++·vscode