两个链表的第一个公共交点

两个链表的第一个公共结点

http://www.nowcoder.com/questionTerminal/6ab1d9a29e88450685099d45c9e31e46

题目中没有说有环还是无环,所以有了下面一大堆长的代码。思路在注释中。

public class Solution {

  public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    // 处理空的情况
    if (pHead1 == null || pHead2 == null) {
      return null;
    }
    // 判断是否有环,并且返回环的入口地址
    ListNode loop1 = EntryNodeOfLoop(pHead1);
    ListNode loop2 = EntryNodeOfLoop(pHead2);
    // 必须都有环或者无环
    // 若一个有环,另一个无环,则返回 null
    if (loop1 == null ^ loop2 == null) {
      return null;
    }
    // 三种情况:1. 同一个入口 2. 不同入口 3. 完全是两个环
    // case 1 同一个入口地址,将入口作为结尾,计算无环情况
    if (loop1 == loop2) {
      return FirstCommonNodeBeforeLoop(pHead1, pHead2, loop1);
    }
    // case 2 不同入口,其中一个增加,必然在某个位置相交
    // 如果循环一圈之后还不相交,说明是 case 3
    ListNode tempNode = loop1;
    do{
      tempNode = tempNode.next;
      if(tempNode == loop2) {
        return loop1;
      }
    } while(tempNode != loop1);
    return null;
  }

  public static ListNode FirstCommonNodeBeforeLoop(ListNode pHead1, ListNode pHead2, ListNode endNode) {
    ListNode curNode1 = pHead1;
    ListNode curNode2 = pHead2;
    // 算 pHead1 长度
    int len1 = 0;
    while (curNode1 != endNode) {
      len1++;
      curNode1 = curNode1.next;
    }
    // 算 pHead2 长度
    int len2 = 0;
    while (curNode2 != endNode) {
      len2++;
      curNode2 = curNode2.next;
    }
    // 快慢指针法
    curNode1 = pHead1;
    curNode2 = pHead2;
    if (len1 >= len2) {
      for (int i = 0; i < len1 - len2; i++) {
        curNode1 = curNode1.next;
      }
    } else {
      for (int i = 0; i < len2 - len1; i++) {
        curNode2 = curNode2.next;
      }
    }
    while (curNode1 != curNode2) {
      curNode1 = curNode1.next;
      curNode2 = curNode2.next;
    }
    return curNode1;
  }

  public static ListNode EntryNodeOfLoop(ListNode pHead) {
    ListNode fastPointer = pHead;
    ListNode slowPointer = pHead;
    do {
      if (fastPointer.next == null || fastPointer.next.next == null) {
        return null;
      }
      // 快慢指针法
      fastPointer = fastPointer.next.next;
      slowPointer = slowPointer.next;
    } while (fastPointer != slowPointer);
    // 寻找交点
    fastPointer = pHead;
    while (fastPointer != slowPointer) {
      fastPointer = fastPointer.next;
      slowPointer = slowPointer.next;
    }
    return fastPointer;
  }
}
全部评论
我也赞同这种解法
点赞 回复 分享
发布于 2020-04-28 09:14

相关推荐

找到实习了&nbsp;给了150一天&nbsp;但是说是低代码&nbsp;值得去吗
码农索隆:是在没实习,可去,待个一两周,不行就润呗
点赞 评论 收藏
分享
在喝茶的牛油很喜欢吃...:今天oc了
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-02 17:28
25届每天都在焦虑找工作的事情0offer情绪一直很低落硬撑着面了一个岗位岗位有应酬的成分面试的时候hr给我出各种场景题问的问题比较犀利&nbsp;有点压力面的感觉感觉有点回答不上来本来就压抑的情绪瞬间爆发了呢一瞬间特别想哭觉得自己特别没用没绷住掉眼泪了事后想想觉得自己挺有病的&nbsp;真的破大防了
喜欢唱跳rap小刺猬...:我觉得没关系吧,之前有一次面试leader给我压力面,我顶住了压力,结果入职的时候发现组里氛围很差,果断跑路。其实从面试就能大概看出组的情况,面试体验好的组倒是不一定好,但是面试体验不好的组。。。就很难说
面试尴尬现场
点赞 评论 收藏
分享
评论
24
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务