持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
1、前言
每天一个算法小练习,本篇使用Java实现。
2、题目描述
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有小于 x 的节点都出现在大于或等于 x 的节点之前。你应当 保留 两个分区中每个节点的初始相对位置。
- 链表中节点的数目在范围 [0, 200] 内
- -100 <= Node.val <= 100
- -200 <= x <= 200
2.1、示例1
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
2.2、示例2
输入:head = [2,1], x = 2
输出:[1,2]
3、解题思路
这道题刚开始读了好几遍才理解题意,尤其是4为什么在3的前面...其实可以这么理解,从链表的头节点开始遍历,只要遇到比 x 大的值就将其取出来,然后再与剩下的原链表拼接起来。那么我们可以找到第一个大于等于x的节点,然后用头插法的方式将小于x的节点插入这个节点之前,即可保持相对顺序不变。
3.1、双指针
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode small = null, current = head, large = null;
while (current != null) {
// 交换条件 小于目标值 不是头部 相邻节点不是都小于目标值
if (current.val < x && large != null && large != small) {
if (small == null) {
// 如果是头部节点需要被交换
large.next = current.next;
current.next = head;
head = current;
small = current;
current = large.next;
} else {
if (current.next == null && head == large) {
// 如果只有两个节点
if (large.val > x) {
// 前一个节点大于目标值则交换
large.next = null;
current.next = large;
head = current;
}
current = null;
} else {
large.next = current.next;
current.next = small.next;
small.next = current;
small = small.next;
current = large.next;
}
}
} else {
//头部或相邻节点都是小于目标值则更新慢指针的值
if ((large == null || large == small) && current.val < x) {
small = current;
}
large = current;
current = current.next;
}
}
return head;
}
}
执行结果:
-
时间复杂度:,n为链表长度
-
空间复杂度:
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊