您的位置:首页 > 其它

将单向链表按某值划分成左边小,中间相等,右边大

2016-04-04 21:23 363 查看
题目:给定一个单向链表的头结点head,节点的值类型是整型,再给定一个整数privot。实现一个调整链表的函数,将链表调整为左部分都是值小于privot的节点,中间部分都是值等于privot的节点,右部分都是大于privot的节点。

例如:链表9-0-4-5-1,pivot=3。

调整后是1-0-4-9-5,也可以是0-1-9-5-4。

解法1:我们可以利用数组额外空间来实现:

1。先遍历一遍链表,得到链表长度。

2。建立一个链表数组。

3。利用三向快排的划分

4。调整数组中的next值。

代码如下:

class Node{
public int value;
public Node next;
public Node(int data){
this.value=data;
}
}
public class quicklist {
public Node listPartition1(Node head,int privot){
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;
}
//调整在数组中的顺序
arrPartion(nodeArr,privot);
//调整赋值
for (i = 0; i != nodeArr.length; i++) {
nodeArr[i-1].next=nodeArr[i];//
}
nodeArr[i-1].next=null;
return nodeArr[0];
}

/**
* 三向切分快排一趟交换,需要三个记录量
* @param nodeArr
* @param privot
*/
private void arrPartion(Node[] nodeArr, int privot) {
int small=-1;
int big=nodeArr.length;
int index=0;
while (index!=big){
if (nodeArr[index].value<privot){
swap(nodeArr,++small,index++);
}else if (nodeArr[index].value==privot){
index++;
}else {
swap(nodeArr,--big,index);
}
}
}

private void swap(Node[] nodeArr, int i, int j) {
Node tmp=nodeArr[i];
nodeArr[i]=nodeArr[j];
nodeArr[j]=tmp;
}
}


解法二:不需要额外空间复杂度的情况下完成调整:

1。将原链表中的所有节点一次划分进三个链表,三个链表分别为small代表左部分,equal代表中间部分,big代表右部分。

例如,链表7-9-1-8-5-2-5,privot=5。在划分之后,small,equal,big分别为:

small:1-2-null

equal:5-5-null

big:7-9-8-null

2。重新串联

3。需要重点判断null。

具体代码这里不予列出。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: