LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素
本文始发于个人公众号:TechFlow,原创不易,求个关注
今天是LeetCode专题第53篇文章,我们一起来看LeetCode第86题,Partition List(链表归并)。
本题的官方难度是Medium,点赞1276,反对296,通过率大约41%。总体来说,这题质量一般,通过率有点高,整体难度偏简单,算是一道链表的基础题。对链表熟悉一些的同学来说,问题不大。
题意
我们首先来看下题意,题意是说给定一个链表以及一个整数x,要求根据x来对链表中的元素进行归并,使得链表的前半部分的结果小于x,后半部分的结果大于等于x。其他元素之间的相对顺序保持不变。
我们来看样例:
Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5
根据3,我们可以将链表当中的元素分成小于3的与大于3的,其中小于3的元素有122,大于等于3的元素有435。我们返回的结果是122和435组成的新链表,并且122和435当中元素的互相顺序没有发生变化。
题解
由于问题当中并没有对我们如何处理链表以及当中的元素做出限制,所以我们可以随意操作这个链表以及其中的数据,很容易想到最简单的方法就是我们根据x将链表当中的元素分成两个部分,分别存入两个链表当中,最后再将这两个链表合并在一起。合并的方式也非常简单,只需要将链表连接在一起即可。
这种思路非常无脑,几乎不涉及什么难点,只需要遍历链表然后分别插入不同的链表即可,最后再把这两个链表合并成一个就搞定了。
我们很容易就可以写出代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
# 创建两个链表
left = ListNode(0)
right = ListNode(0)
# 以及用来遍历这两个链表的指针
ln = left
rn = right
pnt = head
while pnt is not None:
# 小于x则插入left,否则插入right
if pnt.val < x:
ln.next = ListNode(pnt.val)
ln = ln.next
else:
rn.next = ListNode(pnt.val)
rn = rn.next
pnt = pnt.next
# 将left与right合并
ln.next = right.next
return left.next
这样我们固然做了出来,但是我们是在抛弃原链表的基础上做出来的,毕竟开辟了额外的空间。如果我们想要不创建新的链表来解决这题应该怎么办呢?
其实也是很简单的,我们可以遍历链表,如果发现了大于等于x的元素就将它挪到链表的最后。这样当我们遍历结束的时候,就完成了链表的操作。这个思路虽然简单,但是在实现的时候有很多坑点,需要特别小心。
比如我们需要一个值来记录遍历的重点,因为我们在遍历的时候可能会将一些元素挪到链表的最后。所以我们就不能以None来作为终点了,否则会导致死循环。我们需要以大于等于x的第一个元素作为结束点,当遍历到了这个位置的时候结束。还有很多其他关于链表操作的细节,我们可以来查看代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
tail = head
if head is None:
return None
# 找到结尾,当找到了大于等于x的元素就放入结尾后面
while tail.next is not None:
tail = tail.next
# 记录遍历的终点
end_point = None
pnt = ListNode(0)
pnt.next = head
head = pnt
while pnt.next is not end_point:
cur = pnt.next
if cur.val >= x:
# 插入在末尾
tail.next = cur
tail = cur
# 如果终点是None的话则进行更新
# end_point只会更新一次
if end_point is None:
end_point = cur
pnt.next = cur.next
continue
pnt = pnt.next
tail.next = None
return head.next
总结
在这题当中,我们面临的问题是操作链表,将链表当中的一些元素提取出来放在链表最后。无论我们是自己创建新的链表来满足条件,还是在原链表的基础上进行修改,算法的复杂度都是一样的,只是空间复杂度不同,也因此带来的编码复杂度也不同。相对来说,第一种做法更加简单一些,第二种稍稍复杂,但是也并不难,只要熟悉链表的基本操作,应该都是可以做出来的。
关于链表相关的问题我们应该已经做了不少了,今天的题目算是很基础了,相信大家肯定都没有问题,我也就不再赘述了。
今天的文章到这里就结束了,如果喜欢本文的话,请来一波素质三连,给我一点支持吧(关注、转发、点赞)。
本文使用 mdnice 排版
LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素的更多相关文章
- 遍历List集合,删除符合条件的元素
List集合的遍历有三种方式:增强for循环,普通for循环,Iterator迭代器遍历 如果只是对集合进行遍历,以上三种循环都可正常遍历: (1)增强For循环遍历List集合 List<St ...
- [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- Foundation NSMutableArray遍历,选取出符合条件的所有对象
一.查找数组中一个元素,找到后立即返回 当遍历数组只需要返回其中一个符合条件的元素时,使用 indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, ...
- 「C语言」单链表/双向链表的建立/遍历/插入/删除
最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合, ...
- LeetCode 第 287 号问题:寻找重复数,一道非常简单的数组遍历题,加上四个条件后感觉无从下手
今天分享的题目来源于 LeetCode 第 287 号问题:寻找重复数. 题目描述 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个 ...
- 如何正确遍历删除List中的元素(普通for循环、增强for循环、迭代器iterator、removeIf+方法引用)
遍历删除List中符合条件的元素主要有以下几种方法: 普通for循环 增强for循环 foreach 迭代器iterator removeIf 和 方法引用 其中使用普通for循环容易造成遗漏元素的问 ...
- LeetCode 86. 分隔链表(Partition List)
86. 分隔链表 86. Partition List 题目描述 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的 ...
- <数据结构基础学习>(四)链表 Part 1
一.链表基础 动态数组.栈.队列底层都是依托静态数组实现的,靠resize来解决固定容量问题. 链表是真正的动态数据结构,是一种最简单的一种动态数据结构. 更深入的理解引用(或者指针). 更深入的理解 ...
- [LeetCode] Delete Node in a Linked List 删除链表的节点
Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...
随机推荐
- disruptor架构一
Disruptor是一个高性能的异步处理框架,或者可以认为是最快的消息框架(轻量的JMS),也可以认为是一个观察者模式的实现,或者事件监听模式的实现. 在使用之前,首先说明disruptor主要功能加 ...
- linux 在指定文件夹下查找指定字符
grep -r '119090610015743205' /data/html/www/gap_bz_middleware/storage/apiLogs/
- IntelliJ IDEA 2018.3.6 安装、激活 JRebel
在 IntelliJ IDEA 2018.3.6 中安装## JRebel 1.代开 IDEA 开发工具,然后用快捷键 Ctrl+Alt+S 打开设置并搜索 jrebel 插件 2.安装 jrebel ...
- 【C++和C#的区别杂谈】后自增运算符的结算时机
C++和C#的前自增++n和后自增n++,都是先自增后取值和先取值后自增的含义,但在复杂一点的赋值语句中,我发现细节上有很大的差异. 发现这个问题主要是一个无聊的晚上,我想搞清楚后自增是什么时候结算, ...
- robot framework使用小结(二)
robot framework关键字驱动采用分层,结合Template做成数据驱动 我个人觉得不管是关键字驱动还是数据驱动,都是基于模块(或者是函数)的概念 新建测试案例baidu02,添加Libra ...
- Python方法函数记录
目录 python 控制台输出的内容保存到txt 文件 eval函数使用 python 控制台输出的内容保存到txt 文件 import sys class Logger(object): def _ ...
- mybatis源码配置文件解析之五:解析mappers标签(解析XML映射文件)
在上篇文章中分析了mybatis解析<mappers>标签,<mybatis源码配置文件解析之五:解析mappers标签>重点分析了如何解析<mappers>标签中 ...
- .NET Core下开源任务调度框架Hangfire
今天无意中发现了一个很好用的任务调度框架.Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库.在 .net core的环境中,由Core自带的DI管理着生命周期. 相较于qu ...
- (私人收藏)React教程手册
React教程手册 https://pan.baidu.com/s/1ka2PJ54HgqJ8lC6XgbvdLg pedx React 教程 含有3个附件,如下: react.js react-do ...
- MongoDB安装和入门
什么是MongoDB MongoDB是一个文档数据库,提供好的性能,领先的非关系型数据库.采用BSON存储文档数据.2007年10月,MongoDB由10gen团队所发展.2009年2月首度推出.Mo ...