题目 给定一个单向链表的头节点head,节点的值类型是整型,再给定一个 整数pivot。实现一个调整链表的函数,将链表调整为左部分都是值小于 pivot 的节点,中间部分都是值等于pivot的节点,右部分都是值大于 pivot的节点。 除这个要求外,对调整后的节点顺序没有更多的要求。 例如:链表9->0->4->5- >1,pivot=3。 调整后链表可以是1->0->4->9->5,也可以是0->1->9->5->4。总 之,满 足左部分都是小于3的节点,中间部分都是等于3的节点(本例中这个部 分为空),右部分都是大于3的节点即可。对某部分内部的节点顺序不做 要求。
进阶 在原问题的要求之上再增加如下两个要求。 在左、中、右三个部分的内部也做顺序要求,要求每部分里的节点从左 到右的 顺序与原链表中节点的先后次序一致。 例如:链表9->0->4->5->1,pivot=3。 调整后的链表是0->1->9->4->5。 在满足原问题要求的同时,左部分节点从左到 右为0、1。在原链表中也 是先出现0,后出现1;中间部分在本例中为空,不再 讨论;右部分节点 从左到右为9、4、5。在原链表中也是先出现9,然后出现4, 最后出现5。 如果链表长度为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)。
思路 (1)若不考虑稳定性以及空间复杂度,则可以借用荷兰国旗方法。首先将链表节点内容依次存放到数组中,再利用荷兰国旗方法进行调整,最后将数组内容依次串成链表即可。
(2)若考虑稳定性并限制复杂度,则需要设置3条链表:small(用于存放小于pivot的所有数值)、equal(用于存放等于equal的所有数值)、big(用于存放大于pivot的所有数值)。遍历链表,若当前数值小于pivot,则将该数值嫁接到small链表下;若当前数值等于pivot,则将该数值嫁接到equal链表下;若当前数值大于pivot,则将该数值嫁接到big链表下。最后,依次将small、equal、big链表连接到一次。注意连接时是否存在空链表的情况。
package algorithm.section4;
public class SmallerEqualBigger {
public static class Node{
int value;
Node next;
public Node(int value){
this.value = value;
}
}
public static Node method1(Node head, int num){
if (head == null) return null;
Node flag = head;
int length = 0;
while (flag != null){
length++;
flag = flag.next;
}
Node[] arr = new Node[length];
flag = head;
int i = 0;
while (flag != null){
arr[i++] = flag;
flag = flag.next;
}
sort(arr, num);
int cur = 0;
while (cur + 1 < arr.length){
arr[cur].next = arr[cur + 1];
cur++;
}
arr[cur].next = null;
return arr[0];
}
public static void sort(Node[] arr, int num){
int i = -1;
int j = arr.length;
int current = 0;
while (current < j){
if (arr[current].value < num){
swap(arr, current, i + 1);
i++;
current++;
} else if (arr[current].value == num){
current++;
} else {
swap(arr, current, j - 1);
j--;
}
}
}
public static void swap(Node[] arr, int a, int b){
Node f = arr[a];
arr[a] = arr[b];
arr[b] = f;
}
public static Node method2(Node head, int pivot){
Node next = head.next;
Node smallH = null;
Node smallT = null;
Node equalH = null;
Node equalT = null;
Node bigH = null;
Node bigT = null;
while (head != null){
next = head.next;
head.next = null;
if (head.value < pivot){
if (smallH == null) {
smallH = head;
smallT = head;
}
else {
smallT.next = head;
smallT = smallT.next;
}
} else if (head.value == pivot) {
if (equalH == null) {
equalH = head;
equalT = head;
}
else {
equalT.next = head;
equalT = equalT.next;
}
} else {
if (bigH == null) {
bigH = head;
bigT = head;
}
else {
bigT.next = head;
bigT = bigT.next;
}
}
head = next;
}
if (smallT != null) {
smallT.next = equalT == null ? bigH : equalH;
equalT.next = equalT == null ? null : bigH;
return smallH;
} else if (equalT != null){
equalT.next = bigH;
return equalH;
} else {
return bigH;
}
}
public static void print(Node head){
while (head != null) {
System.out.print(head.value + " ");
head = head.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head1 = new Node(7);
head1.next = new Node(9);
head1.next.next = new Node(1);
head1.next.next.next = new Node(8);
head1.next.next.next.next = new Node(5);
head1.next.next.next.next.next = new Node(2);
head1.next.next.next.next.next.next = new Node(5);
print(head1);
// head1 = method1(head1, 4);
head1 = method2(head1, 5);
print(head1);
}
}