链表追赶问题

第一节:求链表倒数第k个节点的值

题目:输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针

分析:首先这个链表时单向链表,并且我们也不知道链表的长度,那么仅仅凭借一个指针来找到倒数第k个节点,就需要知道链表的长度,因此需要先遍历整个链表,得到链表的长度过后,然后再从头结点开始寻找,这种方法显然很笨,那么我们可以用比较简单的方法吗?答案是肯定的,若当一个指针直到最后一个节点为一个flag,我们就可以知道另外一个指针已经指到了倒数第k个节点时,就可以很简单的解决这个问题,正好可以使用快慢指针方法。

> 快慢指针:还可以用于判断链表时否有环。

ElemType ReturnKValue(LinkList list, int k){
    if(NULL == list || k > LengthList(&list)-1)
        return '0';
    LinkList p = list->next;
    LinkList q = list->next;
    while(k--){
        q = q->next;
    } 
    while(q->next != NULL){
        q = q->next;
        p = p->next;
    }

    return p->data;
}

第二节:编程判断两个链表是否相交

题目描述:给出两个单向链表的头指针(如下图所示),

比如h1、h2,判断这两个链表是否相交。这里为了简化问题,我们假设两个链表均不带环。

要想判断两个链表是否相交,其实方法有很多种:

  1. 暴力法:即将链表2中的每一个节点都与链表1中的每一个节点相比较,若存在相等的节点,那么两个链表即相交,这种方法的复杂度为O(Length(list1)*Length(list2);
  2. 将链表2添加到链表1的末尾,然后判断新的链表是否存在环,若存在环则表明两个链表相交(这种方法仅仅局限于两个链表都无环的情况);
  3. 针对第一个链表直接构造hash表,然后检查第二个链表中的每一个节点是否在该hash表中,若存在链表在hash表中,则表明两个链表相交,该方法的;
  4. 如上图所示,若两个链表相交,那么相交节点之后的节点都应该相同,因此我们只需要判断最后两个链表的最后一个节点是否相同即可,若相同则相交(链表无环)。
bool CheckListIntersect(LinkList list1, LinkList list2){
    LinkList p = list1->next;
    LinkList q = list2->next;
    while(p->next != NULL)
        p = p->next;

    while(q->next != NULL)
        q = q->next;

    if(p == q)
        return true;

    return false;
}

上面的方法是已知两个链表都无环的判断情况,那么现在我们不知道两个链表是否有环,该如何判断两个链表是否相交呢?

  1. 首先判断两个链表是否有环:若一个链表有环,而一个链表无环,那么两个链表肯定不相交,若两个链表都无环则可以使用上面的方法;
  2. 若两个链表都有环,那么就求出其中一个链表上俩指针相遇的节点,然后检查该节点是否在另外一个链表上,若在,那么两个链表相交,若不在,则两个链表不相交。

检测链表是否有环:

bool isCircle(Node * head, Node *& circleNode, Node *& lastNode)  {  
    Node * fast = head->next;  
    Node * slow = head;  
    while(fast != slow && fast && slow)  
    {  
        if(fast->next != NULL)  
            fast = fast->next;  

        if(fast->next == NULL)  
            lastNode = fast;  
        if(slow->next == NULL)  
            lastNode = slow;  

        fast = fast->next;  
        slow = slow->next;  

    }  
    if(fast == slow && fast && slow)  
    {  
        circleNode = fast;  
        return true;  
    }  
    else  
        return false;  
}  

判断两个链表是否相交:

bool detect(Node * head1, Node * head2)  
{  
    Node * circleNode1;  
    Node * circleNode2;  
    Node * lastNode1;  
    Node * lastNode2;  

    bool isCircle1 = isCircle(head1,circleNode1, lastNode1);  
    bool isCircle2 = isCircle(head2,circleNode2, lastNode2);  

    //一个有环,一个无环  
    if(isCircle1 != isCircle2)  
        return false;  
    //两个都无环,判断最后一个节点是否相等  
    else if(!isCircle1 && !isCircle2)  
    {  
        return lastNode1 == lastNode2;  
    }  
    //两个都有环,判断环里的节点是否能到达另一个链表环里的节点  
    else  
    {  
        Node * temp = circleNode1->next;  
        while(temp != circleNode1)    
        {  
            if(temp == circleNode2)  
                return true;  
            temp = temp->next;  
        }  
        return false;  
    }  

    return false;  
} 

注:求环和该代码转自july博客:http://blog.csdn.net/v_july_v/article/details/6447013

扩展:求两个链表相交的第一个节点

思路:首先判断两个链表的尾节点是否相等,若相等,则两个链表必定相交。由于相交的部分是等长的,因此我们可以先判断两个链表的长度,若等长,则从第一个节点开始比较,第一个相等的节点即为相交的第一个节点;若不等长呢?这时候我们就可以使用快慢指针:让长的一个链表先走Length(long)-Length(short)步,因为在开始出长的部分肯定不存在相交的节点,这样就可以先等长两个链表,然后通过上述的方法来求第一个节点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值