当前位置: 首页 > article >正文

【链表OJ题(六)】链表分割

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:数据结构
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 链表OJ题(六)
    • 1. 链表分割
      • 思路一 带哨兵位的头结点
      • 思路二 不强行加头结点
  • 7.总结:

上一篇链表OJ题链接:【链表OJ题(五)】合并两个有序链表

链表OJ题(六)

1. 链表分割

链接:CM11 链表分割

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

思路一 带哨兵位的头结点

题目要求我们将小于 x 的节点和大于等于 x 的节点分隔,小于 x 的节点在前,大于等于 x 的节点在后,且不能改变原来的数据顺序

不能改变顺序就比较棘手,如果没有这个条件,我们可以用双指针来写。但是题目既然给出了要求,我们就得想办法解决。

我们创建一个新链表存放小于 x 的值,另一个存放大于等于 x 的值。然后遍历原链表,将符合条件的值放入对应的链表中,最后再将存放小于 x 的值的链表和存放大于等于 x 的值的链表链接起来

那么这过程肯定是尾插,本题使用哨兵位是十分合适的,因为本题有很多的空指针处理的情况,所以我们设定两个哨兵位 lessHeadgreaterHead

再给定两个尾lessTailgreaterTail,用来尾插。 但是最后记得释放哨兵位。

注意如果以 greaterHead 结束的元素不是链表的最后一个元素(即原链表最后一个元素小于 x ),就可能会造成 链表带环 的情况,因为尾插改变前一个链接关系,没有改变自己的后一个链接关系,所以需要断开环,然后将 greaterTailnext 置为空。
在这里插入图片描述

代码:


class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) 
    {
        struct ListNode* lessTail, *lessHead, *greaterTail, *greaterHead;
        // 建立哨兵位
        lessTail = lessHead = (struct ListNode*)malloc(sizeof(struct ListNode));
        greaterTail = greaterHead = (struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* cur = pHead;
        while (cur)
        {
            if (cur->val < x)
            {
                lessTail->next = cur;
                lessTail = cur;
            }
            else
            {
                greaterTail->next = cur;
                greaterTail = cur;
            }
            cur = cur->next;
        }
        // 链接两个链表
        lessTail->next = greaterHead->next;
        greaterTail->next = NULL; // 断开环
		// 拷贝节点,释放哨兵位
        struct ListNode* ans = lessHead->next;
        free(lessHead);
        free(greaterHead);
        return ans;
    }
};

在这里插入图片描述

思路二 不强行加头结点

这道题目不用哨兵位也可以做,但是比较考验细节

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) 
    {
        struct ListNode* lessTail, *lessHead, *greaterHead, *greaterTail;
        lessTail = lessHead = greaterHead = greaterTail = NULL;
        struct ListNode* cur = pHead;
        while (cur)
        {
            if (cur->val < x)
            {
                if (lessTail == NULL)
                {
                    // 第一次尾插
                    lessHead = lessTail = cur;
                }
                else
                {
                    
                    lessTail->next = cur;
                    lessTail = lessTail->next;
                }
                cur = cur->next;
            }
            else
            {
                 if (greaterTail == NULL)
                {
                	// 第一次尾插
                    greaterHead = greaterTail = cur;
                }
                else
                {
                    greaterTail->next = cur;
                    greaterTail = greaterTail->next;
                }
                cur = cur->next;
            }
        }
        // lessHead 为空,说明原链表为空或链表的值全大于 x
        // 且链表尾部的 next 一定为空
        // 返回 greaterHead
        if (lessHead == NULL)
            return greaterHead;
        // 如果 lessHead 和 greaterHead 都不为空
        // 说明正常分割
        // 将其链接,greaterHead 尾部链空
        if (lessHead != NULL && greaterHead != NULL)
        {
            lessTail->next = greaterHead;
            greaterTail->next = NULL;
        }
        // 无论是正常分割,还是链表的值全小于 x
        // 都是返回 lessHead
        return lessHead;
    }
};

在这里插入图片描述

7.总结:

今天我们通过两种思路分析并完成链表分割这道链表OJ题目,也更加深层次了解和使用了哨兵位的头结点这个思路,通过这道题我们也能总结出,当面对尾插且需要处理很多空指针的时候,用哨兵位的头节点这个思路很方便。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述


http://www.kler.cn/a/928.html

相关文章:

  • FPGA的 基本结构(Xilinx 公司Virtex-II 系列FPGA )
  • 嵌入式入门Day42
  • Android SDK下载安装(图文详解)
  • 金融项目实战 04|JMeter实现自动化脚本接口测试及持续集成
  • STM32裸机开发转FreeRTOS教程
  • 从硬件设备看Linux
  • 单调栈图文详解(附Java模板)
  • 【js逆向】hook大全
  • 线程池的使用:如何写出高效的多线程程序?
  • SPI读写SD卡速度有多快?
  • 「SAP ABAP」OPEN SQL(四)【FROM语句】
  • HTTP 协议
  • 体验攻略 | Persona VS. Profile,谁才是研究用户的最佳工具?
  • 手把手教你使用vue创建第一个vis.js
  • 【C++】list的使用 | 模拟实现
  • 5 全面认识java的控制流程
  • 系统集成项目管理工程师:第18章项目风险管理学习笔记
  • 4.类的基本概念
  • 【java】Java并发编程系列-基础知识(非常详细哦)
  • 【Python】正则表达式re库
  • JDBC指南
  • 网易C++实习一面
  • 重构·改善既有代码的设计.04之重构手法(下)完结
  • 【Pytorch】 理解张量Tensor
  • Golang每日一练(leetDay0007)
  • 【基础算法】单链表的OJ练习(6) # 复制带随机指针的链表 #