剑指 Offer 52. 两个链表的第一个公共节点(160. 相交链表&剑指 Offer II 023. 两个链表的第一个重合节点)

题目:

 

 

 

 

思路:

【1】借用辅助空间的方式:利用set存储其中的一条链表,当另一条链表遍历的时候在set判断是否已存入。

【2】利用倒叙的思维,由于相交的部分都是末尾,所以可以考虑剪刀长链表的较长部分,因为这部分绝对不可能相交,如A链表是5,B链表是8,那么相交的部分是小于等于5的。

【3】基于步骤2中的思维在简化一下,既然相交在末尾,那么我把这两条链表组合起来如:A=A+B,B=B+A。那么此时长度必然相等,而且相对于步骤2中的时间复杂度为O(2N),这里时间复杂度为O(N+M)【这里N,M为链表长度,且N>M】,虽然时间复杂度都为O(N),但毕竟还是有些许差距。

代码展示:

//链表相加
//时间1 ms击败98.27%
//内存44.3 MB击败54.76%
//时间复杂度:O(m+n),其中 m 和 n 是分别是链表 headA 和 headB 的长度。两个指针同时遍历两个链表,每个指针遍历两个链表各一次。
//空间复杂度:O(1)。
class Solution {
    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;
    }
}


//长链表去头
//时间1 ms击败98.27%
//内存44.6 MB击败29.35%
//时间复杂度O(2N),可看做O(N),这里可以看做N>M
//空间复杂度O(1)
class Solution {
    ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int countA = 0,countB = 0;
        ListNode tem = headB,temp = headA;
        //优先计算出两个链表的长度,这里次数取最长的链表长度N
        while (temp != null || tem != null){
            if (temp != null){
                countA++;
                temp = temp.next;
            }
            if (tem != null){
                countB++;
                tem = tem.next;
            }
        }
        int dif = Math.abs(countA-countB);
        tem = headB;
        temp = headA;
        //让最长的链表先走相差的步数
        while (dif-- > 0){
            if (countA > countB){
                temp = temp.next;
            }else {
                tem = tem.next;
            }
        }
        //然后按相同的步数走,比对是否有重合之处
        while (temp != null){
            if (temp == tem) return temp;
            temp = temp.next;
            tem = tem.next;
        }
        return null;
    }
}

//使用辅助空间
//时间9 ms击败5.74%
//内存43.8 MB击败96.21%
//时间复杂度O(N+M),可看做O(N)
//空间复杂度O(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) {
        HashSet<ListNode> set = new HashSet<>();
        ListNode temp = headA;
        while (temp != null){
            set.add(temp);
            temp = temp.next;
        }
        temp = headB;
        while (temp != null){
            if (set.contains(temp)) return temp;
            temp = temp.next;
        }
        return null;
    }
}

 

posted @ 2023-02-13 17:22  忧愁的chafry  阅读(9)  评论(0编辑  收藏  举报