160. 相交链表

编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:在节点 c1 开始相交。

在这里插入图片描述

一:暴力法

遍历第一个链表( 长度为m ),每遍历到一个节点,就在第二个链表上( 长度为n ) 顺序遍历每个节点,如果在第二个链表上有一个节点和第一个链表上的节点一样,则说明2个链表在这个节点上重合,这个节点就是他们的公共节点。时间复杂度O(m*n)。

二:辅助栈法

直接上代码

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA||!headB) return nullptr;
    stack<ListNode*> sta1;
    stack<ListNode*> sta2;
    ListNode *p1=headA;
    while(p1!=nullptr)
    {
        sta1.push(p1);
        p1=p1->next;
    }
        ListNode *p2=headB;
    while(p2!=nullptr)
    {
        sta2.push(p2);
        p2=p2->next;
    }
    ListNode *curp=NULL;
    //通过比较栈顶元素,如果相同,则弹出,直到找到最后一个相同的节点
    while(!sta1.empty()&&!sta2.empty()&&sta1.top()==sta2.top())
    {
        curp=sta1.top();
        sta1.pop();
        sta2.pop();
    }
    return curp;
 }

虽然时间复杂度O(m+n)得到了优化,但是增大了空间复杂度,不好。

三、不需要辅助栈
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
     if(!headA||!headB) return nullptr;
     //1、首先得到两个链表的长度
    int longlist=getLength(headA);
    int shortlist=getLength(headB);
    //2、计算出2个链表的节点数之差
    int lengthdif=longlist-shortlist;
    ListNode *longhead=headA;
    ListNode *shorthead=headB;
    if(lengthdif<0)
    {
        longhead=headB;shorthead=headA;
        lengthdif=shortlist-longlist;
    }
    //2、较长的链表先走若干步(这里的步数与节点数之差相同)
        for (int i=0;i<lengthdif;i++)
    {
       longhead=longhead->next;
    }
    //3、同时遍历2个链表,直到找到他们第一个相同的节点
    while(longhead!=nullptr&&shorthead!=nullptr&&longhead!=shorthead)
    {
        longhead=longhead->next;shorthead=shorthead->next;
    }
    return longhead;

    }
    //计算链表长度函数
    int getLength(ListNode * head)
{
    int count=0;
    while(head!=nullptr)
          {
          head=head->next;
          count++;    
          }
         return count;
}

此方法提高了空间效率

四、快慢指针法
 //通过将某一个链表的末尾和开头链接就可以将变成其判断是否有环以及环的入口问题。对于链表环路问题,可以使用快慢指针来解决
 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
  if(!headA||!headB) return nullptr;
 //先构造环
 ListNode *curp=headB;
 while(curp->next)
 {
    curp=curp->next;
 }
 curp->next=headB;
 //构建快慢指针  
 ListNode *fast=headA;
 ListNode *slow=headA;
 while(fast!=nullptr&&fast->next!=nullptr)
 {
     fast=fast->next->next;
     slow=slow->next;
     //第一次相遇
     if(fast==slow)
     {
         fast=headA;
         //第二次相遇
         while(fast!=slow)
         {
            fast=fast->next;
            slow=slow->next;
         }
         //将链表结构复原
         curp->next=nullptr;
         return fast;
     }
 }
 curp->next=nullptr;
 return nullptr;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值