题目描述:
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
。
图示两个链表在节点 c1
开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
思路描述:
对于该题最简单的方法就是暴力穷举法,即以其中一个链作为基础的遍历链表,对于该链表中的每个节点,都从另外一个链表中找是否存在结点和该结点是同一个结点。如果是,就再定义两个游标向后遍历,看后续链表是否相同,相同说明就是该结点,就返回,否则就继续往下遍历。这种方法的时间复杂度为O(m*n),容易实现,但是时间效率不太好。
我们可以利用双指针的的思路来思考这个问题,起始时候两个指针分别指向两个链表的表首,依次往后遍历,如果恰好找到两结点相同,就可以直接返回该结点,否则,继续往后遍历。直到其中一个为空,让其指针指向另一个链表表首,后面会出现另一个指针也为空,做相同的处理。此时,以两个指针为首的链表的长度就可以保证一致了,再做一次遍历就可以得到结果,相当于将两个快慢指针变成两个速度相同的指针。故此时该算法的时间复杂度为O(m+n),相比上个方法,时间复杂度有了很大的提高。
代码:
/**
* 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) {
if(headA==null || headB==null){
return null;
}
ListNode pa=headA;
ListNode pb=headB;
while(pa!=pb){
pa=pa==null?headB:pa.next;
pb=pb==null?headA:pb.next;
}
return pa;
}
}