【 题目】 给定一个单向链表的头节点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的节点即可。 对某部分内部的节点顺序不做要求。
解题思路:
参照荷兰国旗问题,将Node遍历到一个数组中,通过Node的值按照荷兰国旗问题进行比较和交换.整体交换完毕后,数组从头连接到尾部,处理好最后一个Node的next边界问题.
荷兰国旗问题不具备稳定性
public static Node sEB(Node head,int pivot) {
int i = 0;
Node n = head;
while(n != null) {
n = n.next;
i++;
}
Node [] nodes = new Node[i];
n = head;
i = 0;
while(n != null) {
nodes[i++] = n;
n = n.next;
}
int less = -1;
int more = nodes.length;
for(int j = 0; j < nodes.length; j++) {
if(j >= more) {
break;
}
if(nodes[j].data < pivot) {
swap(nodes,j,++less);
}else if(nodes[j].data > pivot) {
swap(nodes,j--,--more);
}
}
for(int j = 1; j < nodes.length ; j++ ) {
nodes[j - 1].next = nodes[j];
}
nodes[nodes.length - 1].next = null;
return nodes[0];
}
测试代码及结果:
public static void main(String[] args) {
Node n1 = new Node(1);
Node n2 = new Node(9);
Node n3 = new Node(3);
Node n4 = new Node(5);
Node n5 = new Node(2);
Node n6 = new Node(7);
n1.append(n2).append(n3).append(n4).append(n5).append(n6);
Node n = sEB(n1,4);
while(n != null) {
System.out.print(n.data + " ");
n = n.next;
}
}
结果:
进阶: 在原问题的要求之上再增加如下两个要求。
在左、 中、 右三个部分的内部也做顺序要求, 要求每部分里的节点从左 到右的顺序与原链表中节点的先后次序一致。 例如: 链表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)。
解题思路:
提前划分出三个区域分别用来存储小于,等于和大于的Node.每个区域用两个变量来记录头和尾.遍历Node将每个节点按要求分发出去,遍历完毕后,连接三个区域(注意空值判断和头尾相连).遍历分发的方式不会打乱Node原来的顺序,此种处理结果具备稳定性.
需要注意看三个区域的空值判断和最后return返回的地方.
public static Node sEB2(Node head, int pivot) {
Node sh = null;
Node st = null;
Node eh = null;
Node et = null;
Node bh = null;
Node bt = null;
Node next = null;
while(head != null) {
next = head.next;
head.next = null;
if(head.data < pivot) {
if(sh == null) {
sh = head;
st = head;
}else {
st.next = head;
st = head;
}
}else if(head.data == pivot) {
if(eh == null) {
eh = head;
et = head;
}else {
et.next = head;
et = head;
}
}else if(head.data > pivot) {
if(bh == null) {
bh = head;
bt = head;
}else {
bt.next = head;
bt = head;
}
}
head = next;
}
if(st != null) {
st.next = eh;
et = et == null ? st : et;
}
if(et != null) {
et.next = bh;
}
return sh != null ? sh : eh != null ? eh : bh;
}
测试代码同第一部分相同,结果如下: