找两个链表的公共节点

首先考虑两个链表无环的情况。

将链表a的尾节点指向头节点从而形成环。用快慢指针遍历链表b,一个一次移动2单位,另一个移动1单位。如果不相遇则不存在公共节点。如果相遇,则让其中一个指针指向b,两个指针以1单位/次的速度移动,直到相遇。相遇时指向的节点就是公共节点的起始。最后记得将a的尾节点恢复。代码如下。

其次考虑有环的情况。用快慢指针探测a中是否有环。如果有则,将使p指向a的尾节点,p的next指向null。按照上面的方法遍历b。如果遍历的过程中遇到p,则将p指向a继续遍历。如果未遇到p或者无环,则不存在公共节点。最后仍然将a的尾节点恢复。

static class LinkedList {
	LinkedList next;
	public LinkedList(LinkedList next) {
		this.next = next;
	}
}

static LinkedList calc(LinkedList a, LinkedList b) {
	// set tail point to a
	LinkedList p = a;
	while (p.next != null) {
		p = p.next;
	}
	p.next = a;

	if (b == null || b.next == null)
		return null;
	LinkedList fast = b.next.next, slow = b.next;
	while (fast != null && fast.next != null && fast != slow) {
		fast = fast.next.next;
		slow = slow.next;
	}
	if (fast != slow) {
		return p.next = null;
	} else {
		slow = b;
		while (fast != slow) {
			fast = fast.next;
			slow = slow.next;
		}
		p.next = null;
		return slow;
	}
}

public static void main(String[] args) {
	LinkedList common = new LinkedList(new LinkedList(new LinkedList(null)));
	LinkedList a = new LinkedList(new LinkedList(common));
	LinkedList b = new LinkedList(new LinkedList(new LinkedList(
			new LinkedList(common))));
	LinkedList r = calc(a, b);
	System.out.println(r == common);

}

Comments

comments powered by Disqus