【题目】
给定一个单链表的头节点head,节点值类型是整型,在给定一个整数pivot,实现一个调整链表的函数,将链表调整为,左边部分是小于pivot的节点,中间是等于的,右侧是大于的
【要求】
调整后节点之间的相对顺序与调整前一致,时间复杂度O(N),空间复杂度O(1)
【思路】
准备3个链表,小于pivot数值的,放在小链表中,等于的放在相等的链表中,大于的放在大链表中。每个链表只需头节点和尾节点即可,3个链表需要6个变量,只需要遍历一次单链表即可,满足题目要求
private static Node listPartition2(Node head, int pivot){
Node sH = null;//小链表的头节点
Node sT = null;//小链表的尾节点
Node eH = null;//相等链表的头节点
Node eT = null;//相等链表的尾节点
Node bH = null;//da链表的头节点
Node bT = null;//大链表的尾节点
Node cur = head;
while (cur != null){
Node next = cur.next;
cur.next = null;
if (cur.value < pivot){
if (null == sH){
sH = cur;
sT = cur;
} else {
sT.next = cur;
sT = cur;
}
} else if (cur.value == pivot){
if (null == eH){
eH = cur;
eT = cur;
} else {
eT.next = cur;
eT = cur;
}
} else {
if (null == bH){
bH = cur;
bT = cur;
} else {
bT.next = cur;
bT = cur;
}
}
cur = next;
}
//拼接3个链表
if (null != sT){
sT.next = eH;
eT = eT == null ? sT : eT;
}
if (null != eT){
eT.next = bH;
}
return sH != null ? sH : (eH != null ? eH : bH);
}
如果不考虑时间复杂度和空间复杂度还有有序的话,可以用数组来实现
private static Node listPartition1(Node head, int pivot){
if (null == head){
return null;
}
Node cur = head;
int count = 0;
while (null != cur){
count++;
cur = cur.next;
}
cur = head;
Node[] arr = new Node[count];
int i = 0;
while (null != cur){
arr[i] = cur;
i++;
cur = cur.next;
}
//快排算法
arrPartition(arr,pivot);
i=1;
//合并数据
while (i != arr.length){
arr[i-1].next = arr[i];
i++;
}
//记得将最后一个结点的下一个节点置为空
arr[i-1].next = null;
return arr[0];
}
//算法类似荷兰国旗问题,小于某值的放在左边,等于的放在中间,大于的放在右边,最后合并数据
private static void arrPartition(Node[] arr, int pivot){
int small = -1;
int index = 0;
int big = arr.length;
while (index < big){
if (arr[index].value < pivot){
swap(arr, ++small, index++);
} else if (arr[index].value == pivot){
index++;
} else {
swap(arr, --big, index);
}
}
}
private static void swap(Node[] arr, int i, int j) {
Node temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
以上都是来自左程云的算法课程的资料。代码是借鉴课程里的代码