package com.niuke;
import java.util.HashMap;
import java.util.Stack;
/**
* Created by admin on 2018/3/11.
* 输入两个链表,找出它们的第一个公共结点。
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
*/
public class FindFirstCommonNode {//比较地址
//不需比较长度找出2个链表的长度
//1 用两个指针扫描”两个链表“,最终两个指针到达 null 或者到达公共结点。
public ListNode findFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode p1=pHead1;
ListNode p2=pHead2;
while(p1!=p2) {
p1=(p1==null?pHead2:p1.next);
p2=(p2==null?pHead1:p2.next);
}
return p1;
//假定 List1长度: a+n List2 长度:b+n, 且 a<b那么 p1 会先到链表尾部,
// 这时p2 走到 a+n位置,将p1换成List2头部接着p2 再走b+n-(n+a) =b-a 步到链表尾部,
// 这时p1也走到List2的b-a位置,还差a步就到可能的第一个公共节点。
// 将p2 换成 List1头部,p2走a步也到可能的第一个公共节点。
// 如果恰好p1==p2,那么p1就是第一个公共节点。或者p1和p2一起走n步到达列表尾部,二
// 者没有公共节点,退出循环。同理a>=b.时间复杂度O(n+a+b)
}
//找出2个链表的长度,然后让长的先走两个链表的长度差,然后再一起走(因为2个链表用公共的尾部)
public ListNode FindFirstCommonNode2(ListNode pHead1, ListNode pHead2) {
int len1=getListLen(pHead1);//求链表pHead1的长度
int len2=getListLen(pHead2);//求链表pHead2的长度
if(pHead1==null||pHead2==null) {
return null;
}
if(len1>len2) {//链表pHead1的长度大于链表pHead2的长度
int len=len1-len2;//长度差
while(len>0) {
pHead1=pHead1.next;
len--;
}
}
if(len2>len1) {//链表pHead2的长度大于链表pHead1的长度
int len=len2-len1;//长度差
while(len>0) {
pHead2=pHead2.next;
len--;
}
}
//开始齐头并进直到找到公共节点
while(pHead1!=pHead2) {
pHead1=pHead1.next;
pHead2=pHead2.next;
}
return pHead1;
}
public int getListLen(ListNode head) {//求链表的长度
int count=0;
while(head!=null) {
head=head.next;
count++;
}
return count;
}
//3运用HashMap的特性
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
HashMap<ListNode,Integer> hashMap=new HashMap<>();
while(pHead1!=null) {
hashMap.put(pHead1,null);
pHead1=pHead1.next;
}
while(pHead2!=null) {
if(hashMap.containsKey(pHead2)) {
return pHead2;
}
pHead2=pHead2.next;
}
return null;
}
//4 两个链表从尾部往前到某个点,节点都是一样的。
// 我们可以用两个栈分别来装这两条链表。一个一个比较出来的值。
public ListNode FindFirstCommonNode4(ListNode pHead1, ListNode pHead2) {
if(pHead1==null||pHead2==null) {
return null;
}
Stack<ListNode> stack1=new Stack<>();
Stack<ListNode> stack2=new Stack<>();
//将两个链表分别压入两个栈中
while (pHead1!=null) {
stack1.push(pHead1);
pHead1=pHead1.next;
}
while (pHead2!=null) {
stack2.push(pHead2);
pHead2=pHead2.next;
}
ListNode result=null;
while(!stack1.isEmpty()&&!stack2.isEmpty()&&stack1.peek()==stack2.peek()) {
stack1.pop();
result=stack2.pop();
}
return result;
}
}
输入两个链表,找出它们的第一个公共结点。
最新推荐文章于 2022-01-13 22:45:15 发布