力扣题目链接
思想(数学):设链表A的长度为a,链表B的长度为b,A到交点D的距离为c,B到交点D的距离为d。显然可以得到两者相交链表的长度为:a - c = b - d ,变换一下式子得到:a + d = b + c.
用一个指针从链表A出发,走完后,接着从链表B出发,另一个指针从链表B出发,走完后,接着从链表A出发。若两个链表相交,当前一个指针走了a + d步时,此时后一个指针走b + c步,即走到了交点。若两个链表不相交,两个指针最终都会走向NULL;
总的来说是让双指针,一个指针走一遍A,再走B。另一个指针走一遍B,再走A。当两个指针走第二个链表时相等的点即为交点。若无交点, 两个指针最终都为NULL;
代码
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode t1 = headA, t2 = headB;while (t1 != t2) {t1 = t1 != null ? t1.next : headB;t2 = t2 != null ? t2.next : headA;}return t1;}
}
思路(非数学):注意本题是找两个链表的交点,即两个节点是相同的,而不是简单的值相等。如果找到交点,那么两个链表后面的节点一定是一样的,因为他们是通过next指针连接起来的。
即如果找到两个链表相等的节点,那么就直接返回这个节点即可,后面的节点就无需再比较了,一定是相等的。
暴力解法是遍历链表A,每遍历一个节点,再遍历链表B看是否有相等的节点,如果有直接返回此节点即可。如果没有继续循环。时间复杂度为0(n*m)
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode t1 = headA;while (t1 != null) {ListNode t2 = headB;while ( t2 != null) {if (t1 == t2) return t1;t2 = t2.next;}t1 =t1.next;}return null;
}
}
法三:首先遍历两个链表求出长度。然后求出两个链表长度的差值,让长的链表向后走差值步,让两个链表对齐。然后同时两个链表同时向后走,如果有相同的节点即找到交点,直接返回。时间复杂度为O(n + m)
代码
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode a = headA, b = headB;int s1 = 0, s2 = 0;while (a != null){a = a.next;s1 ++;}while (b != null) {b = b.next;s2 ++;}a = headA;b = headB;if (s2 > s1) {//交换链表int temp = s1;s1 = s2;s2 =temp;ListNode tempNode = a;a = b;b = tempNode;}int gap = s1 - s2;while (gap -- > 0) { //走到与b同一起点a = a.next;}while (a != null) {if (a == b) return a;a = a.next;b = b.next;}return null;
}
}