单向链表按值划分

【 题目】 给定一个单向链表的头节点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;
	}

测试代码同第一部分相同,结果如下:

 

猜你喜欢

转载自blog.csdn.net/weixin_39445556/article/details/104841819