【基础算法】单链表的OJ练习(4) # 分割链表 # 回文链表 #
文章目录
- 前言
- 分割链表
- 回文链表
- 写在最后
前言
-
本章的
OJ
练习相对前面的难度加大了,但是换汤不换药,还是围绕单链表的性质来出题的。我相信,能够过了前面的OJ
练习,本章的OJ
也是轻轻松松。 -
对于
OJ
练习(3)
:-> 传送门 <- ,着重需要理解的是相交链表那道题的双指针思路,明白为什么可以这样,这样为什么可行。后面遇到类似的题目我还会做么? -
我们每做一道题目,都要深挖他的题目结构,明白为什么可以这样做。我相信如果你这样去做了,并且不断地练习,到后面,每遇到一个题目,你都会有所印象,并能够很快的指出解这道题的思路。
分割链表
-
题目链接:-> 传送门 <- 。
-
题目描述:现有一链表的头指针
ListNode* pHead
,给一定值x
,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。 -
这里的不能改变原来的数据顺序,也就是比
x
小的节点放在其余节点之前时,这些节点的顺序应该与没有放之前是一样的。 -
例如:
2 4 8 5 9 3 5
,给定x = 8
,通过本题目的描述最终的答案应该为:2 4 5 3 5 8 9
。
图解描述:(给定x = 3
)
解题思路:
-
根据题目的意思以及不能改变原来的数据顺序这一特性,我们可以以一种反归并的思想来想这道题。
-
我们遍历原链表并创建两个新链表(这里的新链表表示的是在原链表基础上通过某一条件新连接的一串节点),第一个链表用来尾插小于
x
的节点,第二个链表用来尾插大于等于x
的节点,最后再将第一个链表的尾与第二个链表的头相连接,再返回连接后的整个链表的头,便ok
啦。整个解题思路大致是这样,后面,来谈谈其中的细节。 -
对于创建的两个新链表,都需要哨兵位的头节点来维护,什么是哨兵位的头节点呢?我们可以把哨兵位的头节点当作真实头节点的前驱,它是一个不在答案范围内的节点,但它却可以有效的控制真实的链表。其里面的值可以是随机的,它的
next
初始指向NULL
,直到有节点尾插,它的next
就指向这个节点,而这个节点就是新连接的链表的真实的头。当最后连接完成时,我们想要返回这个链表,应该返回哨兵位的next
,因为哨兵位的next
才是有效的真实的头节点。 -
如果说不用哨兵位的头节点来维护,也是可以的。不过这样会有很多不必要的处理。比如给的原链表是
NULL
,或者两个新链表连接完后其中有一个为空,这些都有可能造成解题出问题,因此需要额外的处理。所以,为了减少这些麻烦,用哨兵位的头节点来维护这两个新链表,上述的这些情况都能够有效避之(上手写代码就有深刻的体会)。 -
有了上面的铺垫我们只需要按照题目要求依次在原链表取节点,然后在对应哨兵位节点指向的链表中尾插,最后将这两个链表连接即可。
下面是代码实现:
这里没学过
c++
也不用担心,代码纯都是C语言
写的。
class Partition {
public:ListNode* partition(ListNode* pHead, int x) {// 创建两个哨兵位的头节点// nhead作为连接比x小的节点// rhead作为连接大于等于x的节点struct ListNode* nhead = (struct ListNode*)malloc(sizeof(struct ListNode));struct ListNode* rhead = (struct ListNode*)malloc(sizeof(struct ListNode));// 操控连接的指针nhead->next = NULL, rhead->next = NULL;struct ListNode* cur = pHead, * cur1 = nhead, * cur2 = rhead;// 遍历原链表while (cur){// 如果小于x就尾插到nheadif (cur->val < x) {cur1->next = cur;cur1 = cur1->next;}else // 如果 >= x 就尾插到rhead{cur2->next = cur;cur2 = cur2->next;}cur = cur->next;}// 两个带哨兵位头节点的链表的连接// 第一个的尾连接第二个的头cur1->next = rhead->next;// 将第二个的尾置为NULLcur2->next = NULL;// 保存连接好的整个链表的头节点(哨兵位头节点的下一个)struct ListNode* newhead = nhead->next;// 分别释放创建的两个哨兵位头节点free(nhead);free(rhead);// 返回新链表的头return newhead;}
};
回文链表
-
题目链接:-> 传送门 <- 。
-
题目描述:给你一个单链表的头节点
head
,请你判断该链表是否为回文链表。如果是,返回true
;否则,返回 false 。 -
回文结构,相信大家已不陌生,类似于
12321
,123321
,6789876
这样的数字,都可称之为回文数。而回文链表也是一样,它每个节点的值组成的数就是一个回文数,例如下面这些链表:
- 那么我们该如何判断一个链表是否为回文链表呢?
解题思路一:
-
我们可以在不破坏原链表的情况下另外创建一个链表,通过遍历原链表依次将原链表上的节点复制尾插到新链表。
-
然后两个链表从头开始比较,如果有一个节点的值不相等就返回
false
。两个链表都遍历结束并且最后遍历的指针都同时指向NULL
,此时返回true
。
下面是代码实现:
bool isPalindrome(struct ListNode* head){struct ListNode* rhead = NULL;struct ListNode* cur = head;// 尾插到新链表while (cur){if (rhead == NULL){rhead = (struct ListNode*)malloc(sizeof(struct ListNode));rhead->val = cur->val;rhead->next = NULL;}else {struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));newnode->val = cur->val;newnode->next = rhead;rhead = newnode;}cur = cur->next;}struct ListNode* cur1 = head, * cur2 = rhead;while (cur1 && cur2){// 有不同直接返回falseif (cur1->val != cur2->val) return false;cur1 = cur1->next;cur2 = cur2->next;}// 如果结束且同时指向NULL,说明回文if (cur1 == NULL && cur2 == NULL) return true;else return false;
}
该思路可以说是暴力解法,效率相对较低,并且开了额外的空间,如果限制不能开额外的空间呢?
解题思路二:
-
上一个思路创建了额外的空间,而本思路将不创建新的空间。
-
首先,找到链表的中间节点,然后从这个中间节点开始,将后面的节点逆转,最后从链表的头节点和逆转后返回的节点分别开始遍历判断。
-
如下图解析:
-
可以看到,整个判断过程是一个循环,如果
rhead
指向空就结束循环,说明是回文链表;如果在循环期间,发现有不一样的值的节点,就直接返回false
。 -
对于 -> 找中间节点 <- 和 -> 反转链表 <- ,在前面已经讲解过了,在这里,我们直接 ctrl + c , ctrl + v 就好。
下面是代码实现:
// 寻找中间节点函数
struct ListNode* middleNode(struct ListNode* head){struct ListNode* fast = head, * slow = head;while (fast && fast->next){fast = fast->next->next;slow = slow->next;}return slow;
}// 反转链表函数
struct ListNode* reverseList(struct ListNode* head){struct ListNode* cur = head;struct ListNode* prev = NULL;while (cur){struct ListNode* tmp = cur->next;cur->next = prev;prev = cur;cur = tmp;}return prev;
}bool isPalindrome(struct ListNode* head){// 找中间节点struct ListNode* mid = middleNode(head);// 从中间节点开始反转链表struct ListNode* rlist = reverseList(mid);// 判断while (rlist){if (head->val != rlist->val) return false;rlist = rlist->next;head = head->next;} return true;
}
写在最后
对于单链表的题目练习,最重要的是思路,我们在数据结构阶段要养成画图的习惯,因为它能帮助我们更好的理解。后续还会有单链表相关的题目练习。
感谢阅读本小白的博客,错误的地方请严厉指出噢!
相关文章:

【基础算法】单链表的OJ练习(4) # 分割链表 # 回文链表 #
文章目录前言分割链表回文链表写在最后前言 本章的OJ练习相对前面的难度加大了,但是换汤不换药,还是围绕单链表的性质来出题的。我相信,能够过了前面的OJ练习,本章的OJ也是轻轻松松。 对于OJ练习(3):-> 传送门 <…...

SpringBoot整合定时任务和邮件发送(邮箱 信息轰炸 整蛊)
SpringBoot整合定时任务和邮件发送(邮箱 信息轰炸 整蛊) 目录SpringBoot整合定时任务和邮件发送(邮箱 信息轰炸 整蛊)1.概述2.最佳实践2.1创建项目引入依赖(mail)2.2 修改yml配置文件2.3 启动类添加EnableScheduling注解2.4 执行的…...

Arduino添加ESP32开发板
【2023年3月4日】 最近要在新电脑上安装Arduino,需要进行一些配置,正好记录一下! Arduino2.0.1 下的开发板添加操作。 ESP32开发板GitHub链接: GitHub - espressif/arduino-esp32: Arduino core for the ESP32Arduino core for…...
Mysql通配符的使用
LIKE操作符 通配符:用来匹配值的一部分的特殊字符。 搜索模式:由字面值,通配符或两者组合构成的搜索条件。 百分号(%)通配符 搜索模式使用例如下 SELECT prod_id, prod_name FROM products WHERE prod_name Like jet%; 这条子句表示&…...

RocketMQ-02
1. 案例介绍 1.1 业务分析 模拟电商网站购物场景中的【下单】和【支付】业务 ###1)下单 用户请求订单系统下单订单系统通过RPC调用订单服务下单订单服务调用优惠券服务,扣减优惠券订单服务调用调用库存服务,校验并扣减库存订单服务调用用户…...

深度学习卷积神经网络CNN之 VGGNet模型主vgg16和vgg19网络模型详解说明(理论篇)
1.VGG背景 2. VGGNet模型结构 3. 特点(创新、优缺点及新知识点) 一、VGG背景 VGGNet是2014年ILSVRC(ImageNet Large Scale Visual Recognition Challenge大规模视觉识别挑战赛)竞赛的第二名,解决ImageNet中的1000类图…...

三:BLE协议架构简介
低功耗蓝牙体系整体架构说明1. PHY(物理层)2. LL(链路层)3. HCI(主机与控制器通信接口)4. L2CAP(逻辑链路控制及适配协议)5. ATT(属性协议)6. GATT(通用属性规范)7. GAP(通用访问规范)8. SM(安全管理)整体架构说明 架构层说明PHY1. 物理层2. 控制射频的发送和接收LL1. 链路层2.…...

小型双轮差速底盘双灰度循迹功能的实现
1. 功能说明 在机器人车体上安装2个 灰度传感器 ,实现机器人按照下图所指定的路线进行导航运动,来模拟仓库物流机器人按指定路线行进的工作过程。 2. 使用样机 本实验使用的样机为R023e样机。 3. 功能实现 3.1 电子硬件 在这个示例中,我们采…...
电子签名?玩具罢了!
需要的前置知识:简单的canvas绘制线路过程 let canvas document.getElementById(id); //id为canvas标签元素的id,或通过其它方法获取标签 let ctx canvas.getContext(2d); //规定为2d绘制图片,即确定为2d画笔 ctx.strokeStyle "whit…...
【Spring Boot读取配置文件的方式】
Spring Boot 支持多种读取配置文件的方式,常用的方式有以下三种: application.properties: Spring Boot 默认会读取该文件作为应用的配置文件。可以在 src/main/resources 目录下创建该文件,并在其中配置应用的属性。 applicat…...
java学习路线规划
java学习路线规划 一、写在前面 兄弟,我整理了一下关于自己之前学习java的一些方向,给你归纳在这里,有空就来看看,希望对你有帮助。 二、java基础篇 1、认识java 了解java历史,大概看看发展史,安装…...

格密码学习笔记(二):连续极小、覆盖半径和平滑参数
文章目录最短距离和连续极小值距离函数和覆盖半径格的平滑参数致谢最短距离和连续极小值 除了行列式,格的另一个基本量是格上最短非零向量的长度,即格中最短距离,其定义为 λ1minx,y∈L,x≠y∥x−y∥minz∈L,z≠0∥z∥.\begin{aligned} …...

ios 通过搜索设备MAC地址绑定
最近做了一个物联网项目,涉及到了设备绑定配网这块,需要了解一下iOS BLE与设备绑定的相关知识点,第一次接触蓝牙相关的项目,所以开始熟悉蓝牙的相关信息。没有去深入研究BabyTooth库,只是感觉CoreBluetooth已经让我更好的理解整个流程这个物联网项目的设备绑定流程是…...

Python实现人脸识别,进行视频跟踪打码,羞羞的画面统统打上马赛克
哈喽兄弟们,我是轻松~ 今天我们来实现用Python自动对视频打马赛克前言准备工作代码实战效果展示最后前言 事情是这样的,昨天去表弟家,用了下他的电脑,不小心点到了他硬盘里隐藏的秘密,本来我只需要用几分钟电脑的&…...
vcf bed起始位置是0还是1
VCF 起始位置为1, POS - position: The reference position, with the 1st base having position 1. Positions are sorted numerically, in increasing order, within each reference sequence CHROM. It is permitted to have multiple records with the same POS. Telome…...

Hexo+live2d | 如何把live2d老婆放进自己的博客
参考:Hexo添加Live2D看板娘最新教程live2d-widgetlive2d-widget-models网页/博客Hexo添加live2d游戏角色看板娘,简易添加,碧蓝航线等live2d新型游戏角色模型(moc3)live2d-moc3jsdelivr方法1可以直接去看参考文章的第一部分的第一篇…...

【微信小程序】-- 页面导航 -- 导航传参(二十四)
💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…...

Pytorch学习笔记#2: 搭建神经网络训练MNIST手写数字数据集
学习自https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html 导入并预处理数据集 pytorch中数据导入和预处理主要用torch.utils.data.DataLoader 和 torch.utils.data.Dataset Dataset 存储样本及其相应的标签,DataLoader在数据上生成一个可迭…...
C语言 猜名次、猜凶手、杨辉三角题目详解
猜名次题目:5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二ÿ…...
蚁群算法负荷预测
%% 清空环境变量 clc clear close all format compact %% 网络结构建立 %% 清空环境变量 clc clear close all format compact %% 网络结构建立 %读取数据 dataxlsread(天气_电量_数据.xlsx,C12:J70);%前7列为每个时刻的发电量 最后列为天气 for i1:58 input(i,:)[data…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...