这个题目是从给定的数字序列中检测其中的循环序列,原问题描述如下
Input sample:
Your program should accept as its first argument a path to a filename containing a sequence of numbers (space delimited). The file can have multiple such lines. E.g
3 4 8 0 11 9 7 2 5 6 10 1 49 49 49 49
1 2 3 1 2 3 1 2 3
Output sample:
Print to stdout the first cycle you find in each sequence. Ensure that there are no trailing empty spaces on each line you print. E.g.
The elements of the sequence are integers in range [0, 99]
The length of the sequence is in range [0, 50]
乍一看,好像很简单的样子,所以,看到这个问题,第一想法就是从后往前检测,碰到相同的数字时开始检测是否为循环。但实际上Cycle Detection这是个非常复杂的问题,如果只是单纯的解决这个题目,应该是可以投机取巧的。网上查了下关于Cycle Detection的一些算法,最出名的应该就是Floyd算法:
Floyd用两个指针,一个慢指针(龟)每次前进一步,快指针(兔)指针每次前进两步(两步或多步效果是等价的,只要一个比另一个快就行,从后面的讨论我们可以看出这一点)。如果两者在链表头以外的某一点相遇(即相等)了,那么说明链表有环,否则,如果(快指针)到达了链表的结尾,那么说明没环。
环的检测从上面的解释理解起来应该没有问题。接下来我们来看一下如何确定环的起点,这也是Floyd解法的第二部分。方法是将慢指针(或快指针)移到链表起点,两者同时移动,每次移动一步,那么两者相遇的地方就是环的起点。(该段引自http://blog.youkuaiyun.com/thestoryofsnow/article/details/6822576)
大致了解了一下这个算法,觉得这道题应该不会是为了考你动态规划及链表方面,为了完成既定任务,看来只能投机取巧了。如果有时间的话,在对这个算法好好研究一下实现。
至于投机取巧的方法,我是把输入列表的最后一个元素作为标志位,然后查找其他相同元素的列表中的索引,并存入indexlst这个列表,如果存在Cycle,那么其长度必然等于indexlst列表中某两个元素之间的距离,dis1 = indexlst[-1] - indexlst[-2],然后在原列表中从后往前选取该长度的序列,如果选取的序列相等,则其就为输出的Cycle。大概思想就是这样,其中还会对诸如
3 4 8 0 11 9 7 2 5 6 10 1 49 49 49 49这样最后几个连续一样的序列进行一个判断。恩..反正最终还是过了