问题描述:![image.png](https://img-blog.csdnimg.cn/img_convert/c86be69e32df5b69dc0a060d9c4fb8ae.png#averageHue=#f8f8f8&clientId=u26fc8b75-234e-4&from=paste&height=411&id=ub25f0b01&originHeight=617&originWidth=2225&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=158263&status=done&style=none&taskId=ua7f5efa6-5f84-4a11-8ade-ffe3201e7cb&title=&width=1483.3333333333333)
题目:输入两个链表找到第一个公共子节点
两个链表的头节点已知,相交之后成为一个单链表,相交的位置和相交前的节点个数未知,要求设计一个算法完成。
思考方式:
相信很多人跟我一样拿到题目之后有一点点思路但是又实现不了,这个时候我们考虑将常用的数据结构和算法思想都过一遍,再想想哪些能解决这个问题。
常用的数据结构:数组,链表,队列,栈,Hash表,集合,树,堆等等
常用的算法:各种排序,双指针,递归等等
代码块
public static ListNode findFirstCommonNodeByMap(ListNode pHead1, ListNode pHead2) {
//1.两个链表有一个为空的情况 则两只链表只能返回空
if (pHead1 == null || pHead2 == null) {
return null;
}
ListNode current1 = pHead1;
ListNode current2 = pHead2;
HashMap<ListNode, Integer> hashMap = new HashMap<ListNode, Integer>();//创建HashMap
while (current1 != null) {//开始遍历
hashMap.put(current1, null);
current1 = current1.next;
}
while (current2 != null) {
if (hashMap.containsKey(current2))
return current2;
current2 = current2.next;
}
return null;
}
public static ListNode findFirstCommonNodeByStack(ListNode headA, ListNode headB) {
Stack<ListNode> stackA = new Stack();
Stack<ListNode> stackB = new Stack();
while (headA != null) {
stackA.push(headA);
headA = headA.next;
}
while (headB != null) {
stackB.push(headB);
headB = headB.next;
}
ListNode preNode = null;
while (stackB.size() > 0 && stackA.size() > 0) {
if (stackA.peek() == stackB.peek()) {
preNode = stackA.pop();
stackB.pop();
} else {
break;
}
}
return preNode;
}
public static ListNode findFirstCommonNodeByCombine(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
ListNode p1 = pHead1;
ListNode p2 = pHead2;
while (p1 != p2) {
p1 = p1.next;
p2 = p2.next;
if (p1 != p2) {
if (p1 == null) {
p1 = pHead2;
}
if (p2 == null) {
p2 = pHead1;
}
}
}
return p1;
}