036两个链表的第一个公共结点
题目:
输入两个链表,找出它们的第一个公共结点。
其实我一开始并不懂什么是公共结点,上网一搜才知道,下面就是两个链表有公共结点
公共结点就是两个链表的结点的地址值相同,不是结点所含的值相同
方法一:HashSet储存法
思路:可以新建一个HashSet的set,然后先将A链表的所有结点存进去,然后在用B的每一个结点来判断,当发现set中存在这个结点,就返回这个结点,这就是两个链表的第一个结点
代码:
//1.Set存储法
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
Set<ListNode> set = new HashSet<>();
ListNode cur1=pHead1;
ListNode cur2=pHead2;
while(cur1!=null){
set.add(cur1);
cur1=cur1.next;
}
while(cur2!=null){
if(set.contains(cur2)) return cur2;
cur2=cur2.next;
}
return null;
}
方法二:普通法
思路:由上图可得,如果两个链表长度不同,两个链表的第一个结点一定不可能在其中一个链表比第二个链表长的那部分,于是我们先算出两个链表的长度,然后移动长的链表到相同长度,然后边移动边判断即可
代码:
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode cur1=pHead1;
ListNode cur2=pHead2;
int length1=FindLength(cur1);
int length2=FindLength(cur2);
if(length1>=length2){
int length=length1-length2;
while(length>0){
cur1=cur1.next;
length--;
}
}else{
int length=length2-length1;
while(length>0){
cur2=cur2.next;
length--;
}
}
while(cur1!=cur2&&cur1!=null){
cur1=cur1.next;
cur2=cur2.next;
}
return cur1;
}
public int FindLength(ListNode pHead){
int length=0;
ListNode p =pHead;
while(p!=null){
length++;
p=p.next;
}
return length;
}
方法三:栈储存法
思路:如果有公共结点,那么公共结点跟之后的结点都会相同,我们可以用两个栈来存储两个链表,从尾部开始判断,如果一旦不相同,返回之前的那个即可
代码:
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1==null||pHead2==null){
return null;
}
Stack<ListNode> stack1 = new Stack<>();
Stack<ListNode> stack2 = new Stack<>();
ListNode cur1=pHead1;
while(cur1!=null){
stack1.push(pHead1);
cur1=cur1.next;
}
cur1=pHead2;
while(cur1!=null){
stack2.push(pHead2);
cur1=cur1.next;
}
ListNode cur2=null;
while(!stack1.isEmpty()&&!stack2.isEmpty()&&stack1.peek()==stack2.peek()){
cur2=stack1.pop();
stack2.pop();
}
return cur2;
}