Java算法题-解析 "分隔链表" 算法问题
题目:
给定一个链表和一个特定值 x
,将链表中所有小于 x
的节点移到大于或等于 x
的节点之前,保持原有相对位置。
引言:
"分隔链表" 是一个关于链表操作的问题。解决这个问题需要对链表的基本操作有一定的理解,同时需要找到一种方法来重新组织链表中的节点。通过解答这个问题,我们可以提升对链表操作的考虑,同时也能拓展对链表处理的能力。
算法思路:
为了实现链表的分隔,我们可以维护两个新的链表,一个链表用来存放小于 x
的节点,另一个链表用来存放大于等于 x
的节点。具体思路如下:
- 创建两个链表
lessThanX
和greaterThanOrEqualX
,分别用于存放小于x
的节点和大于等于x
的节点。 - 遍历原链表,将小于
x
的节点添加到lessThanX
链表中,将大于等于x
的节点添加到greaterThanOrEqualX
链表中。 - 将
lessThanX
链表的尾节点指向greaterThanOrEqualX
链表的头节点,从而将两个链表连接起来。 - 最后,将
greaterThanOrEqualX
链表的尾节点指向null
,防止形成环。
代码实现:
以下是使用 Java 实现的 "分隔链表" 算法的示例代码:
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
public class PartitionList {
public ListNode partition(ListNode head, int x) {
ListNode lessThanX = new ListNode(0);
ListNode greaterThanOrEqualX = new ListNode(0);
ListNode lessThanXDummy = lessThanX;
ListNode greaterThanOrEqualXDummy = greaterThanOrEqualX;
while (head != null) {
if (head.val < x) {
lessThanX.next = head;
lessThanX = lessThanX.next;
} else {
greaterThanOrEqualX.next = head;
greaterThanOrEqualX = greaterThanOrEqualX.next;
}
head = head.next;
}
greaterThanOrEqualX.next = null; // To prevent cyclic link
lessThanX.next = greaterThanOrEqualXDummy.next;
return lessThanXDummy.next;
}
}
算法分析:
- 时间复杂度:遍历一次原链表,将节点分别添加到两个新链表中,所以时间复杂度为 O(n),其中 n 是链表的长度。
- 空间复杂度:算法使用了两个新的链表,所以空间复杂度为 O(n),其中 n 是链表的长度。
示例和测试:
假设给定链表 1 -> 4 -> 3 -> 2 -> 5 -> 2
和 x = 3
,根据算法,将链表分隔后得到 1 -> 2 -> 2 -> 4 -> 3 -> 5
。
我们可以使用以下代码进行测试:
public class Main {
public static void main(String[] args) {
PartitionList solution = new PartitionList();
ListNode head = new ListNode(1);
head.next = new ListNode(4);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(2);
head.next.next.next.next = new ListNode(5);
head.next.next.next.next.next = new ListNode(2);
int x = 3;
ListNode result = solution.partition(head, x);
System.out.print("Resulting linked list: ");
while (result != null) {
System.out.print(result.val + " ");
result = result.next;
}
}
}
总结:
"分隔链表" 算法题要求将链表中小于给定值 x
的节点移到大于等于 x
的节点之前,是一个关于链表操作的问题。通过实现这个算法,我们可以提升对链表操作的考虑,同时也能拓展对链表处理的能力。这个问题强调了如何维护两个新的链表,然后连接它们以重新组织链表中的节点。