剑指 Offer 52. 两个链表的第一个公共节点(JavaScript语言)

思路一(哈希集合法)

(注意:空间复杂度为O(n),与题意不符合,不过也是一种思路)
将一个链表的每个节点保存在set中。遍历另一个链表,看这个链表的节点在不在set中,在就返回。遍历完未返回就说明没有公共节点,返回null。

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function(headA, headB) {
    var set = new Set();//注意:空间复杂度O(n)
    while(headA) {
        set.add(headA);
        headA = headA.next;
    }
    while(headB) {
        if(set.has(headB)) return headB;
        else headB = headB.next;
    }
    return null;  
};

思路二(快慢指针法)

求出headA的长度m,求出headB的长度n。哪个链表长度长,就让他先走m-n绝对值长,然后两个指针同时走,走到的第一个公共节点即为所求值。没有公共节点的话,返回null。

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function(headA, headB) {//快慢指针法
    var curheadA = headA;//遍历headA的指针
    var curheadB = headB;//遍历headB的指针
    var m = 0;//记录headA长度
    var n = 0;//记录headB长度
    while(curheadA) {//计算headA长度
        m++;
        curheadA = curheadA.next;
    }
    while(curheadB) {//计算headB长度
        n++;
        curheadB = curheadB.next;
    }
    curheadA = headA;
    curheadB = headB;
    if(m <= n) {//长度更长的链表先走abs(m-n)下
        for(let j = 1; j <= n-m; j++) {
            curheadB = curheadB.next;
        }
    }else {
        for(let i = 1; i <= m-n; i++) {
            curheadA =curheadA.next;
        }
    }
    while(curheadA && curheadB) {//同时走,遇到的第一个相同的节点就是返回值
        if(curheadA == curheadB) return curheadA;
        else {
            curheadA = curheadA.next;
            curheadB = curheadB.next;
        }
    }
    return null;//无公共节点的情况
};

思路三(双指针法,浪漫相遇)

思路参考自:图解 双指针法,浪漫相遇
我们使用两个指针curheadA,curheadB分别指向两个链表 headA,headB 的头结点,然后同时分别逐结点遍历,当 curheadA到达链表 headA 的末尾时,重新定位到链表 headB 的头结点;当 curheadB 到达链表 headB 的末尾时,重新定位到链表 headA 的头结点。

这样,当它们相遇时,所指向的结点就是第一个公共结点。

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function(headA, headB) {//双指针法,浪漫相遇
    
    var curheadA = headA;//遍历headA的指针
    var curheadB = headB;//遍历headB的指针
    while(curheadA != curheadB) {      
        curheadA = curheadA == null ? headB : curheadA.next;
        curheadB = curheadB == null ? headA : curheadB.next;
    }
    return curheadA;
    
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值