LeetCode0166-两个链表相交的点


/**
* 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
* */

import java.util.HashSet;
import java.util.List;


public class Num160_missLinkedlist {
    //方法一:正常map匹配法
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        HashSet<ListNode> first = new HashSet<ListNode>();
        // HashSet<ListNode> second = new HashSet<>();
        while(headA!=null ){
            first.add(headA);
            headA = headA.next;
        }

        while(headB!=null){
            if(first.contains(headB)){
                return headB;
            }
            headB = headB.next;
        }
        return null;
    }
//
    //方法二:双指针法,只要有交点,A走完自己后,走B的路,B走完之后,走A的路,相当于求了两个数的和,两个数在和上一定会相遇
    public static ListNode getIntersectionNode2(ListNode headA, ListNode headB){

        if (headA == null || headB == null) {return null;}

        ListNode first = headA;
        ListNode second = headB;

        while(first != second){
//            这样分开也不对,相当于一个循环里面,对first操作了2次,第一次:赋值headB,第二次,移动指针
//            if(first==null){
//                first=headB;
//            }
//            if(second ==null){
//                second = headA;
//            }
//            first = first.next;
//            second = second.next;

            if(first==null){
                first=headB;
            }else{
                first = first.next;
            }
            if(second ==null){
                second = headA;
            }else{
                second = second.next;
            }

        }
        return first;
    }

    //    参考答案
    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            if (headA == null || headB == null) {
                return null;
            }
            ListNode pA = headA, pB = headB;
            while (pA != pB) {
                pA = pA == null ? headB : pA.next;
                pB = pB == null ? headA : pB.next;
            }
            return pA;
        }
    }

////        为啥这样会超时? 因为第43行往下不对
////        Boolean tag = true;
////        int count=0;
//        while (first.next != second.next){
//
//            if(first.next ==null){
//                // first.next为空时,表示走到了frist的最后一个节点,若直接给first.next赋值,相当于给共同节点赋值,即:
//                // A\B两个链的最后一个节点统一指向了B的开头,这样操作的是每个节点指针的地址,更改了原来联调的结构
//                first.next = headB;
//            }
//            if(second.next == null){
//                second.next = headA;
//            }
//            first = first.next;
//            second = second.next;
//            }
//        return first;
//        }
//




    public static void main(String[] args) {
        ListNode a0= new ListNode(4);

        ListNode c0 = new ListNode(1);
        ListNode c1 = new ListNode(8);
        ListNode c2 = new ListNode(4);
        ListNode c3 = new ListNode(5);

        ListNode b0 = new ListNode(5);
        ListNode b1 = new ListNode(6);

        a0.next=c0;
        b0.next=b1;
        b1.next=c0;
        c0.next=c1;
        c1.next=c2;
        c2.next=c3;

        getIntersectionNode2(a0,b0);

    }

}

 

posted on 2021-06-30 10:31  cStream  阅读(72)  评论(0)    收藏  举报