• [2014校招笔试]判断单链表是否有环?


    某互联网企业的笔试题:判断单链表是否有环?如果有环,如何在O(N)的时间复杂度和O(1)的空间复杂度得到这个环的入口点?

    问题1:如何判断有环呢?

    这个方法可能不只一种,但是在网上看到的那个类似于两个人跑步的解法最容易让人接受。两个人跑步,同时跑,但一个人在跑的快,一个人跑的慢,如果他们在一个环形操场上跑的话,肯定他们要不只一次的相遇。判断环也是这个原理,两个指针p和q,一开始p和q都指向头结点,如果p每次移动一步,q每次移动两步,那么p和q如果再一次相遇,那么有环,如果走到null,那么肯定没环。

    问题2:如何得到环的入口?

    这个需要一点的推导,假设在p和q第二次相遇的时候(第一次相遇在头结点)p走了s步,那么q肯定走了2s步,所以有:

    2*s-s=nr.  其中,r是环的长度,n是圈数。

    如果记从头结点到环入口点的距离为a,从换入口点到相遇点得距离为x,那么有

    s=a+x. (q和p相遇时,p肯定没有走完一圈)

    由上面两个公式又能推出:

    s=a+x=nr

    如果链表总长度为L的话,那么r=L-a, 有

    a+x=(n-1)r+(L-a)

    a=(n-1)r+(L-a-x)

    其中L-a-x是p要走完一圈还要走的步数。

    因此可以这样找到环的起始点:p和q相遇后,再增加一个指针k,k指向链表的头结点,然后k开始移动,一次一步,p继续移动,一次一步,那么当k走到环的入口点,p也一定到了环的入口点。因此k和p的相遇点,就是换的入口点。

    扩展问题1:如何求循环链表上任一点a的最远点b.

    一个圆上最远点就是同一条直径上的另一个点嘛。

    方法还是指针p和q, 均从a点出发,p一次走1步,q一次走2步,当q回到a时,p指的点就是另一端的点。因为q走一圈的时候,p肯定只走了半圈。

    扩展问题2:判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)

    其实只要把第一链表首位相连,判断相交和找相交点就变成了与问题1和2相同的问题。

    其实判断两个单链表是否相交有更简单的方法,只需要判断链表的最后一个点是否相同就可以。因为如果相交,就像轨道并轨一样,两个链表的最后一个节点肯定是相同的。

    还可以通过两个栈来得到第一个相交的点,将Link A的节点全部压入栈SA,将Link B的节点全部压入栈SB,然后同时出栈,最后一个相同的点就是相交点。

    还有另外一种判断方法,容易得到Link A的长度LA,和Link B的长度LB,那么假设LA>LB那么LA先走LA-LB步,LB在从走,两个指针肯定会相交,相交的第一个点就是要找的点。

  • 相关阅读:
    Java基础加强-内部类及代理
    金额货币转换函数
    SAP ABAP exporting list to memory ...SUBMIT 程序传输屏幕参数
    得到时间戳的函数
    alv行可编辑时带出描述
    ALV编辑行内容有改变时候操作
    ALV判断修改后是否有不合法数据,有则选中错误行,高亮度显示。
    数据字典的QUAN DEC类型与ABAP P型转换
    屏幕编程 F4的帮组用法
    read table 时关键字TRANSPORTING NO FIELDS的用法
  • 原文地址:https://www.cnblogs.com/orchid/p/3346052.html
Copyright © 2020-2023  润新知