【面试经典 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)。


写在最后

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

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

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

相关推荐
ragnwang29 分钟前
C++ Eigen常见的高级用法 [学习笔记]
c++·笔记·学习
yuanManGan1 小时前
数据结构漫游记:静态链表的实现(CPP)
数据结构·链表
lqqjuly3 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
冰红茶兑滴水4 小时前
云备份项目--工具类编写
linux·c++
刘好念4 小时前
[OpenGL]使用 Compute Shader 实现矩阵点乘
c++·计算机图形学·opengl·glsl
酒鬼猿5 小时前
C++进阶(二)--面向对象--继承
java·开发语言·c++
姚先生975 小时前
LeetCode 209. 长度最小的子数组 (C++实现)
c++·算法·leetcode
小王爱吃月亮糖6 小时前
QT开发【常用控件1】-Layouts & Spacers
开发语言·前端·c++·qt·visual studio
chenziang16 小时前
leetcode hot100 删除链表的第n个节点
算法·leetcode·链表
aworkholic6 小时前
opencv sdk for java中提示无stiching模块接口的问题
java·c++·opencv·jni·opencv4android·stiching