题目描述:
输入两个链表,找出它们的第一个公共结点。
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
使用java中的hashmap,可以方便的解决这个问题。
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
// 利用hashmap
ListNode current1 = pHead1;
ListNode current2 = pHead2;
HashMap<ListNode, Integer> hashMap = new HashMap<ListNode, Integer>();
while (current1 != null) {
hashMap.put(current1, null);
current1 = current1.next;
}
while (current2 != null) {
if (hashMap.containsKey(current2))
return current2;
current2 = current2.next;
}
return null;
}
从给出的链表结构可以看出,这个一个单向链表。所以说,加入两个链表有公共结点,那么它们的尾部一定是相同的。我们可以借助于栈先进后出的特点,将这两个链表存入栈中,从后向前遍历,直到找到第一个不同的结点,那么这个结点的后一个结点就是第一个相同的节点,这种方法的时间复杂度为O(n+m)(n、m即为两个链表各自的长度),但是这样需要用到额外的空间。
我们可以先得到两个链表的长度,然后先遍历比较长的那个链表,直到两个链表的长度相等时,再同时遍历两个链表,找到相同的结点。这样的时间复杂度也为O(n+m),但是不需要辅助空间。
public ListNode FindFirstCommenNode2(ListNode pHead1, ListNode pHead2) {
ListNode current1 = pHead1;
ListNode current2 = pHead2;
if (pHead1 == null || pHead2 == null)
return null;
int length1 = getLength(current1);
int length2 = getLength(current2);
if (length1 >= length2) {
int length = length1 - length2;
for (int i = 0; i < length; i++)
current1 = current1.next;
} else {
int length = length2 - length1;
for (int i = 0; i < length; i++)
current2 = current2.next;
}
while (current1 != current2) {
current1 = current1.next;
current2 = current2.next;
}
return current1;
}
public int getLength(ListNode pHead) {
int length = 0;
ListNode current = pHead;
while (current != null) {
length++;
current = current.next;
}
return length;
}