(链表)求相交链表交点
1.问题描述:
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
2.使用双指针解决该题
2.1 思路与图解
若相交,链表A: a+c, 链表B : b+c. a+c+b+c = b+c+a+c 。则会在公共处c起点相遇。若不相交,a +b = b+a 。因此相遇处是NULL
2.2 代码实现:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if(headA == null || headB == null) return null; ListNode pA = headA, pB = headB; // 在这里第一轮体现在pA和pB第一次到达尾部会移向另一链表的表头, 而第二轮体现在如果pA或pB相交就返回交点, 不相交最后就是null==null while(pA != pB) { pA = pA == null ? headB : pA.next;
//三目运算
//表达式1 ? 表达式2:表达式3;
//表达式1必须是一个条件表达式或者返回值必须为boolean类型的。表达式2和表达式3则没有什么要求。
//当表达式1的返回值为true时,返回表达式2的值。否则,返回表达式3的值。
//当pA==null时,PA=headB,也就是B链表的头结点;当PA!=null 时,PA=PA.next
pB = pB == null ? headA : pB.next; } return pA; }
2.3 复杂度分析
时间复杂度 : O(m+n)。
空间复杂度 : O(1)。
3.使用哈希表解题
3.1 思路:遍历链表 A 并将每个结点的地址/引用存储在哈希表中。然后检查链表 B 中的每一个结点 bi是否在哈希表中。若在,则 bi为相交结点
3.2 代码实现
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { Set s = new HashSet(); ListNode p = headA; ListNode q = headB; //定义一个set之后,不断遍历p链表,然后将所有元素加入到set中 while(p!=null) { s.add(p); p = p.next; } while(q!=null) { //遍历q链表,如果q链表的元素出现在set中, //重合,而这个重合的就是第一个相交的节点就说明 //p和q两个链表有 if(s.contains(q)) { return q; } q = q.next; } return null; } }
3.3复杂度分析
时间复杂度 : O(m+n)。
空间复杂度 : O(m) 或 O(n)。