分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击人工智能教程
package live.every.day.ProgrammingDesign.CodingInterviewGuide.List;
/**
* 将单向链表按某值划分成左边小、中间相等、右边大的形式
*
* 【题目】
* 给定一个单向链表的头节点head,节点的值类型是整型,再给定一个整数pivot。实现一个调整链表的函数,将链表调整为左部分都
* 是值小于pivot的节点,中间部分都是值等于pivot的节点,右部分都是值大于pivot的节点。除这个要求外,对调整后的节点顺序没
* 有更多的要求。
*
* 【难度】
* 中等
*
* 【解答】
* 普通解法的时间复杂度为O(N),额外空间复杂度为O(N),就是把链表中的所有节点放入一个额外的数组中,然后统一调整位置的办
* 法。具体过程如下:
* 1、先遍历一遍链表,为了得到链表的长度,假设长度为N。
* 2、生成长度为N的Node类型的数组nodeArr,然后遍历一次链表,将节点依次放进nodeArr中。本文在这里不用LinkedList或
* ArrayList等Java提供的结构,因为一个纯粹的数组结构比较利于步骤3的调整。
* 3、在nodeArr中把小于pivot的节点放在左边,把相等的放中间,把大于的放在右边。也就是改进了快速排序中partition的调整
* 过程,即如下代码中的arrPartition方法。实现的具体解释请参看"数组类似partition的调整"问题,这里不再详述。
* 4、经过步骤3的调整后,nodeArr是满足题目要求的节点顺序,只要把nodeArr中的节点依次重连起来即可,整个过程结束。
* 全部过程请参看如下代码中的listPartition1方法。
*
* @author Created by LiveEveryDay
*/
public class PartitionSingleListLeftMiddleRight1 {
public static class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
}
}
public static Node listPartition1(Node head, int pivot) {
if (head == null) {
return head;
}
Node cur = head;
int i = 0;
while (cur != null) {
i++;
cur = cur.next;
}
Node[] nodeArr = new Node[i];
i = 0;
cur = head;
for (i = 0; i != nodeArr.length; i++) {
nodeArr[i] = cur;
cur = cur.next;
}
arrPartition(nodeArr, pivot);
for (i = 1; i != nodeArr.length; i++) {
nodeArr[i - 1].next = nodeArr[i];
}
nodeArr[i - 1].next = null;
return nodeArr[0];
}
private static void arrPartition(Node[] nodeArr, int pivot) {
int small = -1;
int big = nodeArr.length;
int index = 0;
while (index != big) {
if (nodeArr[index].data < pivot) {
swap(nodeArr, ++small, index++);
} else if (nodeArr[index].data == pivot) {
index++;
} else {
swap(nodeArr, --big, index);
}
}
}
private static void swap(Node[] nodeArr, int a, int b) {
Node tmp = nodeArr[a];
nodeArr[a] = nodeArr[b];
nodeArr[b] = tmp;
}
public static void main(String[] args) {
Node node1 = new Node(9);
Node node2 = new Node(0);
Node node3 = new Node(4);
Node node4 = new Node(5);
Node node5 = new Node(1);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = null;
Node n = listPartition1(node1, 3);
while (n != null) {
System.out.printf("%d ", n.data);
n = n.next;
}
}
}
// ------ Output ------
/*
1 0 5 4 9
*/