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

题目:输入两个链表,找出它们的第一个公共结点。

解析:这题严谨的做法应该是先判断两个链表相交是否有环,下面两种做法是可以合并一起的,即有环选1,没换选2。
1.有环的做法
①定义一个快指针(一次移动一个结点)指向第一个链表和一个慢指针(一次移动两个结点)指向第二个链表,同时从链表头移动;
②如果链表相交后结点成环,快慢指针一定会在环里相遇,记录此时相遇的结点;
③定义另一指针指向其中一链表的头部,与指向相遇结点的指针同时开始移动(均移动一步),直到他们相遇,此时相遇的结点就是两个链表的第一个公共节点;(这里涉及到一个公式的推导)

public ListNode FindFirstCommonNode2(ListNode pHead1, ListNode pHead2) {
    //1两个链表其中有一个为null,则没有交点
  if (pHead1==null||pHead2==null)  return null;
    //2定义快指针first和second
  ListNode first = pHead1, second = pHead2;
  boolean flag = false;
    //3快慢指针同时移动直到他们相遇,记录相遇的结点
  while(first != null&&second!=null&&first.next!=null){
   first = first.next.next;
   second = second.next;
   if(second == first){
    flag = true;
    break;
   }
  }
    //4指针first从头开始移动,second从当前环的节点开始移动(两个指针只移动一步)
  if (flag){
   first = pHead1;
   while(first!=second){
    first = first.next;
    second = second.next;
   }
   return first;
  }
  return null;
 }

2.没有环的做法
①先遍历两个链表,记录链表的长度len1和len2;
②比较len1和len2的大小,记录最长的链表和链表之间的长度差diff;
③最长的链表移动diff后剩下的长度与较短链表一样,记录此时移动到的结点node;
④此时同时从较短链表的头部和较长链表的结点node开始移动(一个节点),直到他们的结点的值相等,找到第一个公共的交点。

public ListNode FindFirstCommonNode1(ListNode pHead1, ListNode pHead2) {
  if(pHead1 == null || pHead2 == null)  return null;
  int len1 = 0, len2 = 0;
  int diff = 0;
  ListNode head1 = pHead1, head2 = pHead2;
  //pHead1的长度
  while (head1 != null){
   len1++;
   head1 = head1.next;
  }
  //pHead2的长度
  while (head2 != null){
   len2++;
   head2 = head2.next;
  }
  //长的链表先移动两个链表之间的差异距离
  if (len1>len2){
      diff = len1-len2;
      while (diff!=0){
       pHead1 = pHead1.next;
       diff--;
      }
  }else{
   diff = len2-len1;
   while (diff!=0){
    pHead2 = pHead2.next;
    diff--;
   }
  }
  //两个链表同时移动一个节点。直到他们的节点值相等,找到公共节点
  while(pHead1 != null){
   if (pHead1 == pHead2){
    return pHead1;
   }
   pHead1 = pHead1.next;
   pHead2 = pHead2.next;
  }
  return null;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值