题目
输入两个链表,找出它们的第一个公共节点。
如下面的两个链表:
在节点 c1 开始相交。
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Reference of the node with value = 8 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 输出:Reference of the node with value = 2 输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 输出:null 输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 解释:这两个链表不相交,因此返回 null。
题目地址:剑指 Offer 52. 两个链表的第一个公共节点 - 力扣(LeetCode)
与另一题相同:160. 相交链表 - 力扣(LeetCode)
方法1:栈(不华丽)
思路
思路很简单,将两个链表分别入栈,然后出栈去比较栈顶元素,有交点的两个链表他们入栈之后的栈顶肯定是相同的,那么交点就在第一个不相同的栈顶元素的next。
代码
class Solution {ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA==null || headB==null)return null;Stack<ListNode> stackA = new Stack<>();Stack<ListNode> stackB = new Stack<>();ListNode p1 = headA;ListNode p2 = headB;while (p1!=null){stackA.add(p1);p1 = p1.next;}while (p2!=null){stackB.add(p2);p2 = p2.next;}//最后两个节点不相同,那就是没有相交的节点if (stackA.peek()!= stackB.peek() )return null;while (!stackA.isEmpty() && !stackB.isEmpty()){if (stackA.peek()==stackB.peek()){stackA.pop();stackB.pop();continue;}else{return stackA.peek().next;}}//既然代码走到了这里,说明不是没有交点// 而是这两个栈的其中一个已经空了,那么没空的那个栈的栈顶元素.next就是交点//或者两个栈都空了if (stackA.isEmpty() && !stackB.isEmpty()){return stackB.peek().next;}else if (!stackA.isEmpty() && stackB.isEmpty()){return stackA.peek().next;}else {return headA;}}}
这是我自己想出来的方法,过肯定能过,但是不算一个好方法。
方法2:双指针浪漫相遇
思路来自题解
剑指 Offer 52. 两个链表的第一个公共节点 - 力扣(LeetCode)
思路
思路很简单,定义两个指针分别指向两个链表的头结点,然后两个指针同步往后走,每次都比较看是否相同,如果某个指针走完了自己的链表,那就开始走另一个链表,这样总能相遇,相遇的那个节点就是相交节点。
例如:没有交点的情况,最后都会走到null,null==null,所以就返回了null,正确
再来看有交点的情况
如果有交点且两个链表长度相同,则两指正同步走直接就能比对出来
代码
class Solution {ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA==null||headB==null)return null;ListNode p1 = headA;ListNode p2 = headB;while (true){if (p1 == p2)return p1;if (p1 == null){p1 = headB;continue;}if (p2 == null){p2 = headA;continue;}p1 = p1.next;p2 = p2.next;}}}
效果就比较好