剑指Offer——两个链表的第一个公共节点

题目:输入两个链表,返回两者的第一个公共节点

在这里插入图片描述

如上图,根据链表的结构,可以看出当两个当链表交汇后,之后的所有节点都肯定会一样。

所以第一个问题就要先确定输入的两个链表是否存在公共节点。可以分别遍历链表到末尾,如果两个尾节点一样,可以确认存在公共节点,否则一定不存在。

接下来需要确认公共节点的位置,容易看出如果两个链表长度一样的话,那么声明两个分别指向两个链表的头指针,以同样速度遍历链表,当两者首次相等时,即找到链表公共节点。

如果链表长度不一致怎么办呢?其实也很简单,第一次遍历的时候我们就已经可以确认链表长度。对于长的那个链表,比如上图的链表1-2-3,比4-5多1个节点,那么指向可以令1-2-3那个链表的指针先移动1个节点,之后可以认为节点2和节点4之后的链表长度一样了。之后同时前进两个节点后,在节点6获得相同节点。

代码如下:

ListNode* FirstCommonNodesInLists(LinkList a, LinkList b){ 
  if(a==nullptr||b==nullptr) return nullptr;
  int LenA = 0;
  int LenB = 0;
  
  ListNode *NodeA = a;
  ListNode *NodeB = b;
  while(NodeA!=nullptr){
    LenA++;
    NodeA = NodeA->Next;
  }

  while(NodeB!=nullptr){
    LenB++;
    NodeB = NodeB->Next;
  }

  if(NodeA!=NodeB) return nullptr;//如果两者尾指针不相等,则肯定没有共同节点

  NodeA = a; NodeB = b;

  //节点数多的先走,直到两个指针之后的链表长度一致
  int step = abs(LenA - LenB);
  if(LenA >= LenB) for(int i = 0; i < step; ++i) NodeA = NodeA->Next;
  else  for(int i = 0; i < step; ++i) NodeB = NodeB->Next;

  while(NodeA!=NodeB&&NodeA!=nullptr){
    NodeA = NodeA->Next;
    NodeB = NodeB->Next;
  }
  return NodeA;//如果空,则表明无共同节点,否则返回第一个共同节点

}

其他思路

本题还有其他思路,我们可以很容易从头到尾遍历两个链表,如果两者尾指针相等,则确定有公共节点。此时只要想办法让两个链表的指针往回走,直到找到最后一个相同的节点即为公共节点。
由于链表只能单向遍历,要想往前比较,就需要用到栈。申请两个栈空间,遍历链表的同时将链表节点放进栈,遍历完成后比较栈顶元素,如果相等则弹出。直至两者不相等为止。

本题代码放在这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值