2.07链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA
= 2, skipB = 3 输出:Intersected at ‘8’ 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。 在 A 中,相交节点前有 2
个节点;在 B 中,相交节点前有 3 个节点。 示例 2:输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3,
skipB = 1 输出:Intersected at ‘2’ 解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。 在 A 中,相交节点前有 3 个节点;在 B
中,相交节点前有 1 个节点。 示例 3:输入: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 。提示:
listA 中节点数目为 m listB 中节点数目为 n 0 <= m, n <= 3 * 104 1 <= Node.val <=
105 0 <= skipA <= m 0 <= skipB <= n 如果 listA 和 listB 没有交点,intersectVal
为 0 如果 listA 和 listB 有交点,intersectVal == listA[skipA + 1] ==
listB[skipB + 1]
思路一
借鉴大神操作,追击相遇问题
太巧妙了
如果两个链表相交,两个指针最终会在相交节点相遇,因为它们遍历的总长度是相同的(先走完一个链表,再走另一个链表的剩余部分)。
如果两个链表不相交,两个指针最终会同时指向 null,这是因为它们走过的路径长度相同,但是都走完了两个链表,最后都指向了 null。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode A = headA;ListNode B = headB;//当A B不相遇时while(A != B){//A如果不为空,A向后走否则将A指向B链首A = A != null ? A.next : headB;//B如果不为空,B向后走,否则将B指向A的链首B = B != null ? B.next : headA;}//返回重合点return A;}
}
思路二
比较麻烦,但是更加容易想到哦
- 找出A ,B链表的长度差并将两条链表尾部对齐
- 假设A长B短,那么从B的开头,A的(lenA - lenB)位置开始遍历
- AB同时向后移动,直到AB找到相同的后缀
- 找不到就直接返回null
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {//找出A ,B链表的长度差并将两条链表尾部对齐//假设A长B短,那么从B的开头开始遍历//AB同时向后移动,直到AB找到相同的后缀//找不到就直接返回nullListNode A = headA, B = headB;int lenA = 0 , lenB = 0;//寻找A的长度while(A != null){lenA ++;A = A.next;}//寻找B的长度while (B != null){lenB ++;B = B.next;}//重置A, B指针为初始位置A = headA;B = headB;//让A为最长链表的头,lenA为其长度if(lenB > lenA){//交换A ,B指针位置(交换三步走)ListNode tmpNode = A;A = B;B = tmpNode;//交换lenA ,lenBint tmp = lenA;lenA = lenB;lenB = tmp;}//求A B长度差int gap = lenA - lenB;//让A和B在同一起点上while (gap > 0){A = A.next;--gap;}//当A不为空时,遇到相同则返回while (A != null){if(A == B){return A;}A = A.next;B = B.next;}return null;}
}