题目:输入两个链表,找出他们的第一个公共节点
可以发现两个链表在第一个节点重合之后不会再分开了
简单多说一句不会分开的原因,因为单向链表的节点只有一个nextNode指向下一个节点,那么如果该节点重合了,那么后面的节点一定是同一个
如果直观点对这个图形进行解释就是两个链表重合之后呈现一个Y型而不是一个X型
解决问题
一般这种问题要用两个类似指针的东西,一个先走,一个后走
所以我们先遍历找到两个链表的长度m和n,如果m大,m比n大多少,比如说k,那么先让m先走k步,然后n和m再一起走
package jianZhiOffer;
/*
* 面试题52:两个链表的第一个公共节点
* 题目:输入两个链表,找出他们的第一个公共节点
*/
public class Demo52 {
public class List{
public List(int val) {
this.val = val;
}
int val;
List next;
}
public static void main(String[] args) {
Demo52 my = new Demo52();
List p1 = my.new List(1);
List a = my.new List(2);
List b = my.new List(3);
List c = my.new List(6);
List d = my.new List(7);
List p2 = my.new List(4);
List e = my.new List(5);
p1.next = a;
a.next = b;
b.next = c;
c.next = d;
p2.next = e;
e.next = c;
System.out.println(FindFirstCommonNode(p1,p2));
}
public static int FindFirstCommonNode(List p1,List p2) {
//得到2个链表的长度
int length1 = GetListLength(p1);
int length2 = GetListLength(p2);
int length = length1-length2; //两个链表长度之差
List pLong = p1;
List pShort = p2;
if(length2>length1)
{
pLong = p2;
pShort = p1;
length = length2-length1;
}
//先在长链表上走几步,再同时在两个链表上遍历
for(int i=0;i<length;i++)
pLong = pLong.next;
while((pLong!=null) && (pShort!=null) && (pLong!=pShort)) {
pLong = pLong.next;
pShort = pShort.next;
}
//得到第一个公共节点
List pFirstCommonNode = pLong;
return pFirstCommonNode.val;
}
public static int GetListLength(List p) {
int length = 0;
List pNode = p;
while(pNode!=null) {
++length;
pNode = pNode.next;
}
return length;
}
}
看看别的思路:
1、用HashMap:
第一个while是把pHead1的所有节点都放进去。
第二个while开始,对pHead2的每个节点都用 containsKey 方法来判断。
因为在前一种思路中,要求得两个链表的长度就需要对两个链表进行一次遍历,用HashMap的方法其实更加节省时间。
package jianZhiOffer;
import java.util.HashMap;
import jianZhiOffer.Demo52.List;
public class Demo5201 {
public class List{
public List(int val) {
this.val = val;
}
int val;
List next;
}
public static void main(String[] args) {
Demo5201 my = new Demo5201();
List p1 = my.new List(1);
List a = my.new List(2);
List b = my.new List(3);
List c = my.new List(6);
List d = my.new List(7);
List p2 = my.new List(4);
List e = my.new List(5);
p1.next = a;
a.next = b;
b.next = c;
c.next = d;
p2.next = e;
e.next = c;
System.out.println(FindFirstCommonNode(p1,p2));
}
public static int FindFirstCommonNode(List p1,List p2) {
List current1 = p1;
List current2 = p2;
HashMap<List,Integer> map = new HashMap<List,Integer>();
while(current1!=null) {
map.put(current1, null);
current1 = current1.next;
}
while(current2!=null) {
if(map.containsKey(current2))
return current2.val;
current2 = current2.next;
}
return 0;
}
}