两链表是否有环+是否相交

1. 分析

来源:《程序员代码面试指南》(第2版)左程云

  1. 单链表是否有环
  2. 如果一个有环,一个没有,则肯定不想交
  3. 如果都没有环,找到相交点,参考
  4. 如果都有环,分三种情况:
    • 情况一,环入口一致,相交点在入口前面
    • 情况二,环入口不一致,且loop1 loop2在环中不连通,则不相交
    • 请款三,环入口不一致,且loop1 loop2在环中连通,则两个入口都算相交点

2. 代码

public class IntersectList(){
    public Node getIntersectNode(Node head1, Node head2){
        //是否相交,如果相交,返回相交的结点
        if(head1 == null || head2 = null){
            return null;
        }
        //两链表的环
        Node loop1 = getLoopNode(head1);
        Node loop2 = getLoopNode(head2);
        //如果都没环
        if(loop1 == null && loop2 == null){
            return noLoop(head1, head2);
        }
        //如果都有环
        if(loop1 != null && loop2 != null){
            return bothLoop(head1,head2);
        }
        //如果一个有环,一个没有,则肯定不想交
        return null;
    }
    public Node getLoopNode(Node head){
        //链表中是否有环,环的入口
        if(head == null ||head.next == null) return null;
          Node node1 = head;
          Node node2 = head;
          while(node1!=null && node1.next!=null){
              //先寻找是否有环
              //快慢指针一起出发
              node1 = node1.next.next;
              node2 = node2.next;
              if(node1 == node2){//如有环,快慢指针在环中某个结点相遇
                  //使用同速的双指针,找到环的入口
                  //起点分别是head和环中相遇点
                  node2=pHead;
                  while(node1 != node2){
                      node1= node1.next;
                      node2 = node2.next;
                  }
                  return node1;
              }         
          }
          return null;
    }
    public Node noLoop(Node head1, Node head2,Node tail = null){
        //两链表都没环,找相交结点
        //若相交则从相交的结点到tail是相同的
        //@param tail表示表尾,默认为空,可初始化未非空值,方便复用
        if(head1 == null || head2 = null){
            return null;
        }
        int n = 0;
        Node cur1 = head1;
        Node cur2 = head2;
        //计算长度差n 
        while(cur1 != tail) {
            n++;
            cur1 = cur1.next;
        }
        while(cur2 != tail){
            n--;
            cur2 = cur2.next;
        }
        //两尾不同则不相交
        if(cur1 != cur2) return null;
        //cur1 指向长链表,cur2指向短的
        cur1 = (n > 0) ? head1 : head2;
        cur2 = (cur1 == head1) ? head2 : head1;
        //长链表先走n步
        while(n>0){
            cur1 = cur1.next;
            n--;
        }
        //两指针再一起走
        while(cur1 != cur2){
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        //相遇的第一个节点就是交点
        return cur1;
    }
    public Node bothLoop(Node head1,Node loop1, Node head2, Node loop2){
        //两链表都有环,找相交结点
        //三种情况
        //情况一,环入口一致,相交点在入口前面
        //情况二,环入口不一致,且loop1 loop2在环中不连通,则不相交
        //请款三,环入口不一致,且loop1 loop2在环中连通,则两个入口都算相交点
        Node cur1 = null;
        Node cur2 = null;
        if(loop1 == loop2 ){
            //用noLoop()找到环入口前的相交点,注意第三个参数设为环入口
            return noLoop(head1, head2, loop1);
        }else{

            for(cur1 = loop1.next; cur1 != loop1; cur1 = cur1.next){
                //情况三
                if(cur1 == loop2) return loop1;
            }
            //情况二
            return null;
        }

    }
}

3. 复杂度

空间:O(1)
时间:O(M+N)

全部评论

相关推荐

今天周一休息,突发奇想写一篇阶段总结。如题,我已经去了一个和Java彻底毫无关联的行业。曾经我以为自己能在计算机行业发光发热,没想到刚入行一年多就当了逃兵。从最开始的热爱到现在一看到代码就厌恶,不知道自己经历了什么。所以我去干什么了?答案是:在成都当了租房销售。上班那会压力大了就念叨着去干租房中介,但是一直下不去这个决心,想着自己学了四年多的计算机知识,终究还是不甘心。终于在某一天准备八股文的时候,看着无数篇和工作内容关系不大的理论知识,那一刻下定决心,决定尝试一下销售行业,也算是给自己一个交代。后面阴差阳错的投了成都自如去当租房管家,没想到面试很顺利,在当天一百多个面试的人里面,我成为了为数不多通过的几个幸运儿之一。目前已经培训通过,正式入职,也开了单,也有压力但是每天过得很开心,真心喜欢那种和人交流的感觉,哪怕是最后没有选择找我租房。说这些也是想告诉那些大三,大四正在找Java实习而焦虑的同学:你们现在还年轻,选择很多,容错率也很高,可以尽情去尝试自己喜欢的行业和工作。不用因为某一次的面试没通过或者简历石沉大海而焦虑,更不用因为身边人都在挤编程的独木桥就强迫自己跟风。也算是自己的碎碎念吧,也希望自己能在新的领域取得一点小成就。也祝牛油工作顺利!
沉淀小子:干啥都不丢人啊,生存是必须要的,销售很考验一个人综合素质能力的,好的销售人脉和资源可不比写字楼的白领差啊
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 一张图晒出你司的标语 #
4234次浏览 75人参与
# AI面会问哪些问题? #
27302次浏览 545人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
14960次浏览 219人参与
# 你的实习产出是真实的还是包装的? #
19958次浏览 342人参与
# 找AI工作可以去哪些公司? #
8782次浏览 225人参与
# 春招至今,你的战绩如何? #
64037次浏览 575人参与
# 米连集团26产品管培生项目 #
13269次浏览 285人参与
# 从事AI岗需要掌握哪些技术栈? #
8671次浏览 293人参与
# 你做过最难的笔试是哪家公司 #
32715次浏览 223人参与
# 中国电信笔试 #
31617次浏览 284人参与
# 投递几十家公司,到现在0offer,大家都一样吗 #
340650次浏览 2173人参与
# 阿里笔试 #
178203次浏览 1311人参与
# 第一份工作一定要去大厂吗 #
14308次浏览 122人参与
# 金三银四,你的春招进行到哪个阶段了? #
22001次浏览 280人参与
# 沪漂/北漂你觉得哪个更苦? #
9691次浏览 193人参与
# HR最不可信的一句话是__ #
6123次浏览 113人参与
# 应届生第一份工资要多少合适 #
20651次浏览 86人参与
# AI时代,哪个岗位还有“活路” #
11346次浏览 339人参与
# 春招你拿到offer了吗 #
830934次浏览 9986人参与
# 长得好看会提高面试通过率吗? #
22418次浏览 254人参与
# 聊聊你的职场新体验 #
336392次浏览 1894人参与
# 学历对求职的影响 #
664972次浏览 4249人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务