本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给定一个链表,给定一个值num
让链表分区成三个部分,前面是小于num的,中间是等于num的,后面是大于num的。
思路
这个题目我们需要知道分区的根本是什么,是不是让一个链表变成了三个部分,或许有人会认为我这是废话文学,你往后看就知道了。
我们分成三个部分,就是三个小链表,定义6个变量
小于区域的头: shead
小于区域的尾: stail
等于区域的头: ehead
等于区域的尾: etail
大于区域的头: bhead
大于区域的尾: btail
然后我们开始遍历链表,拿到一个元素之后就看看它是哪个区域的,然后就把它放到它应该在的地方,最后把它们连起来就可以,就很简单了。我们直接看代码
代码
public static Node listPartition(Node head, int num){
Node sHead = null;
Node sTail = null;
Node eHead = null;
Node eTail = null;
Node bHead = null;
Node bTail = null;
Node cur = head;
//注意点1:我们需要一个next来记录下一个位置,为什么又这个操作呢?下面我会解答
Node next = null;
while(cur != null){
next = cur.next;
cur.next = null;
if(cur.value < num){
if(sHead == null){
sHead = cur;
sTail =cur;
}else{
sTail.next = cur;
sTail = sTail.next;
}
}else if(cur.value == num){
if(eHead == null){
eHead = cur;
eTail =cur;
}else{
eTail.next = cur;
eTail = eTail.next;
}
}else if(cur.value > num){
if(bHead == null){
bHead = cur;
bTail =cur;
}else{
bTail.next = cur;
bTail = bTail.next;
}
}
//注意点2:不要忘记让cur后移要不然循环会结束不了
cur = next;
}
//注意点3:返回头结点的时候要看看各个部分是否有值
if(sHead != null){
sTail.next = eHead;
}
if(eHead != null){
eTail.next = bHead;
}
return sHead == null ? (eHead == null ? bHead : eHead) : sHead;
}
这个代码还是有很多需要注意的地方的。
注意点1:这个地方有个next是为了防止cur.next = null的时候把整个链表的后半段丢失。为什么我们要让cur的后一个结点为nill呢?
因为我们要斩断cur与原链表的连接,这样刚好的能让它融入到新的链表。