两个链表相交的一系列问题【js实现】

题目:

在本题中,单链表可能有环也可能无环,给定两个单链表的头结点phead1 和phead2,这两个链表可能相交也可能不相交,请实现一个函数,如果两个链表相交,请返回相交的第一个节点,如果不相交,直接返回null

要求:如果链表1的长度为n,链表2的长度为m,时间复杂度请达到O(N + M),额外空间复杂度达到O(1)

这个问题可以拆分成三个子问题:

一:如何判断一个链表是否有环,如果有,则返回第一个进入环的子节点,没有返回null

二:如花判断两个无环链表是否相交,相交则返回第一个相交的节点,不相交则返回null

三:如何判断两个有环链表是否相交,相交则返回第一个相交的节点,不相交则返回null

注意:如果一个链表有环,另一个链表无环,它们是不可能相交的,直接返回null

 

代码:

        //判断是否有环
            function getLoopNode(head) {
                if (head == null || head.next == null || head.next.next == null) {
                    return null;
                }
                var n1 = head.next;
                var n2 = head.next.next;
                while (n1 != n2) {
                    if (n2.next == null || n2.next.next == null) {
                        return null
                    }
                    n1 = n1.next;
                    n2 = n2.next.next;
                }
                n2 = head;
                while (n1 !== n2) {
                    n1 = n1.next;
                    n2 = n2.next;
                }
                return n1;
            }

            //两个无环链表
            function noLoop(pHead1, pHead2) {
                if(pHead1 == null || pHead2 == null){
                    return null;
                }
                var cur1 = pHead1;
                var cur2 = pHead2;
                var n = 0;
                while(cur1.next !== null){
                    n++;
                    cur1 = cur1.next;
                }
                while(cur2 !== null){
                    n--;
                    cur2 = cur2.next;
                }
                if(cur1 !== cur2){
                    return null;
                }
                cur1 = n > 0 ? pHead1 : pHead2;
                cur2 = cur1 === pHead1 ? pHead2 : pHead1;
                n = Math.abs(n);
                while(n != 0){
                    n--;
                    cur1 = cur1.next;
                }
                while(cur1 != cur2){
                    cur1 = cur1.next;
                    cur2 = cur2.next;
                }
                return cur1;
            }

            //两个有环
            function bothLoop(pHead1, loop1, pHead2, loop2) {
                    var cur1 = null;
                    var cur2 = null;
                    if (loop1 == loop2) {
                        if (pHead1 == null || pHead2 == null) {
                            return null;
                        }
                        var cur1 = pHead1;
                        var cur2 = pHead2;
                        var n = 0;
                        while (cur1.next !== null) {
                            n++;
                            cur1 = cur1.next;
                        }
                        while (cur2 !== null) {
                            n--;
                            cur2 = cur2.next;
                        }
                        if (cur1 !== cur2) {
                            return null;
                        }
                        cur1 = n > 0 ? pHead1 : pHead2;
                        cur2 = cur1 === pHead1 ? pHead2 : pHead1;
                        n = Math.abs(n);
                        while (n != 0) {
                            n--;
                            cur1 = cur1.next;
                        }
                        while (cur1 != cur2) {
                            cur1 = cur1.next;
                            cur2 = cur2.next;
                        }
                        return cur1;
                    }else{
                        cur1 = loop1.next;
                        while(cur1 != loop1){
                            if(cur1 == cur2){
                                return loop1;
                            }
                            cur1 = cur1.next;
                        }
                        return null
                    }
                }

                //总函数
                function getIntersectNode(pHead1,pHead2){
                    if(pHead1 == null || pHead2 == null){
                        return null;
                    }
                    var loop1 = getLoopNode(pHead1);
                    var loop2 = getLoopNode(pHead2);
                    if(loop1 == null && loop2 == null){
                        return noLoop(pHead1,pHead2)
                    }
                    if(loop1 !== null && loop2 !== null){
                        return bothLoop(pHead1,loop1,pHead2,loop2)
                    }
                    return null;
                }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值