30. (★★典型的双指针问题)剑指 Offer 52. 两个链表的第一个公共节点

题目描述

输入两个链表,找出它们的第一个公共节点。

如下面的两个链表

在节点 c1 开始相交。

思路:自己没有思路,看了答案

第一个公共节点为 node ,链表 headA的节点数量为 a,链表 headB的节点数量为 b ,两链表的公共尾部的节点数量为 c ,则有:

头节点 headA 到 node 前,共有 a - c 个节点;
头节点 headB 到 node 前,共有 b - c个节点;

指针 A 先遍历完链表 headA ,再开始遍历链表 headB ,当走到 node 时,共走步数为:
a + (b - c)

指针 B 先遍历完链表 headB ,再开始遍历链表 headA ,当走到 node 时,共走步数为:
b + (a - c)

双指针问题!

双指针就是两个同时移动的指针,也可以不同时移动;

可以从同一边移动,也可以从不同的两端移动;但是需要拿到尾端的位置才能从尾端移动,一般是数组!

双指针要对移动的步数敏感!也要将两个指针移动的步数和敏感!

代码

1)浪漫的双指针!空间复杂度 O(N+M);时间复杂度O(1);只有额外的两个指针的空间开销

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //主要问题是,节点走的顺序和快慢不同
        //两个指针,将1和2分别都走一遍时,走过的路程就是一样的!
        //所以在都剩下 公共区域的长度时,在到达公共点时,走过的路程长度也一样
        ListNode node1 = headA;
        ListNode node2 = headB;
        while(node1 != node2){//判断地址
            //没走到尾时,往后移,走到尾就去另一个链表中
            //这里是 node1 != null 因为需要走到 null这一步,需要完成在两轮走完,都到了null,进行终止循环的判断
            node1 = node1 != null ? node1.next : headB;
            node2 = node2 != null ? node2.next : headA;
        }
        return node1;
    }
}

2)哈希表;遍历第一个链表,将节点都存起来;再遍历另一个链表,比较是否包含!

时间复杂度原则上来说和 双指针一样,但是实际执行有差距

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> set = new HashSet<>();
        while(headA != null){
            set.add(headA);
            headA = headA.next;
        }
        while(headB != null){
            if(set.contains(headB)) return headB;
            headB = headB.next;
        }
        return null;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值