LinkLists 把一个链表根据一个值分成两半 @CareerCup

Write code to partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x.

写代码把一个链表根据值x分成两块,来使得所有小于x的节点都在大等于x的节点的前面。

例如:

1->3->7->5->2->9->4 按照5来分 变成:

1->3->2->4->7->5->9 这样所有小于5的都在大等于5之前了


思路:

建立两个链表,第一个存放比x小的节点,第二个存放大等于x的节点。

最后合并两个链表。这样做法还是in place的


package LinkLists;

import CtCILibrary.LinkedListNode;

public class S2_4 {

	// 建立两个链表,第一个存放比x小的节点,第二个存放大等于x的节点
	public static LinkedListNode partition(LinkedListNode node, int x) {
		LinkedListNode beforeStart = null;		// 第一个链表开始位置
		LinkedListNode beforeEnd = null;			// 第一个链表结束位置
		LinkedListNode afterStart = null;			// 第二个链表开始位置
		LinkedListNode afterEnd = null;			// 第二个链表结束位置
		
		while (node != null) {
			LinkedListNode next = node.next;	// 保存下一个节点
			node.next = null;							// 断开当前节点和下一个节点连接
			if(node.data < x) {		// 小的被分到第一个链表
				if(beforeStart == null) {	// 链表还没建时
					beforeStart = node;
					beforeEnd = beforeStart;
				} else{							// 链表已经存在时
					beforeEnd.next = node;
					beforeEnd = node;
				}
			} else{						// 大的被分到第二个链表
				if(afterStart == null) {
					afterStart = node;
					afterEnd = afterStart;
				} else{
					afterEnd.next = node;
					afterEnd = node;
				}
			}
			node = next;
		}
		
		if(beforeStart == null) {	// 所有的节点都大于x
			return afterStart;
		}
		
		beforeEnd.next = afterStart;		// 连接两个链表
		return beforeStart;
	}
	
	// 另一种方法,书中说的是能避免使用多个变量。
	// 但我觉得这种方法没什么意义,因为这种方法反而会更慢些,而且合并出来的也不是stable的
	// 为了完整性,也把这种解法附在这里。思想是链表的头插代替上面的尾插
	public static LinkedListNode partition2(LinkedListNode node, int x) {
		LinkedListNode beforeStart = null;
		LinkedListNode afterStart = null;

		/* Partition list */
		while (node != null) {
			LinkedListNode next = node.next;
			if (node.data < x) {
				/* Insert node into start of before list */
				node.next = beforeStart;
				beforeStart = node;	
			} else {
				/* Insert node into front of after list */
				node.next = afterStart;
				afterStart = node;
			}	
			node = next;
		}

		/* Merge before list and after list */
		if (beforeStart == null) {
			return afterStart;
		}

		LinkedListNode head = beforeStart;
		while (beforeStart.next != null) {
			beforeStart = beforeStart.next;
		}
		beforeStart.next = afterStart;
		return head;
	}
	
	public static void main(String[] args) {
		/* Create linked list */
		int[] vals = {1, 3, 7, 5, 2, 9, 4};
		LinkedListNode head = new LinkedListNode(vals[0], null, null);
		LinkedListNode current = head;
		for (int i = 1; i < vals.length; i++) {
			current = new LinkedListNode(vals[i], null, current);
		}
		System.out.println(head.printForward());

		LinkedListNode clone = head.clone();
		
		/* Partition */
		LinkedListNode h = partition(head, 5);
		LinkedListNode h2 = partition2(clone, 5);

		/* Print Result */
		System.out.println(h.printForward());
		System.out.println(h2.printForward());
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值