Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 仅使用列表查找线性时间内列表中不存在的最小非负整数_List_Haskell - Fatal编程技术网

List 仅使用列表查找线性时间内列表中不存在的最小非负整数

List 仅使用列表查找线性时间内列表中不存在的最小非负整数,list,haskell,List,Haskell,考虑一个函数minout::[Int]->Int,它获取一个不同的非负整数列表,并返回列表中不存在的最小非负整数。如果输入有重复项,函数的行为无关紧要。这是否可以在线性时间内实现,只使用列表(没有数组、向量或其他具有有效随机访问的数据结构) (这出现了。)如果l的所有数字都在0和(长度l)-1之间,那么最小值l是长度l,否则,它位于[0..(长度l-1)]。因此minout l始终位于[0..(长度l)],并且只有[0..(长度l-1)]中的l元素相关。我们可以丢弃剩下的元素。利用这一思想,我们

考虑一个函数
minout::[Int]->Int
,它获取一个不同的非负整数列表,并返回列表中不存在的最小非负整数。如果输入有重复项,函数的行为无关紧要。这是否可以在线性时间内实现,只使用列表(没有数组、向量或其他具有有效随机访问的数据结构)


(这出现了。)

如果
l
的所有数字都在
0
(长度l)-1
之间,那么
最小值l
长度l
,否则,它位于
[0..(长度l-1)]
。因此
minout l
始终位于
[0..(长度l)]
,并且只有
[0..(长度l-1)]
中的
l
元素相关。我们可以丢弃剩下的元素。利用这一思想,我们可以实现线性时间分治解决方案。与合并排序不同,在递归的每个步骤中,我们只递归到两个子列表中的一个子列表中,每个子列表的大小最多为原始列表的一半(在做了一些线性工作之后)。这给出了线性时间复杂度

minout :: [Int] -> Int
minout = minoutaux 0
    where
    minoutaux :: Int -> [Int] -> Int -- \list base -> smallest integer >= base not occuring in list
    minoutaux base [] = base
    minoutaux base [x] = base + (if x==base then 1 else 0)
    minoutaux base xs = if (length smallpart == n2) then  minoutaux (base+n2) bigpart else minoutaux base smallpart
        where
        n = (length xs)
        n2 = n `div` 2
        smallpart = [x | x <- xs , base <= x , x < base + n2]
        bigpart = [x | x <- xs, base + n2 <= x, x < base + n]
minout::[Int]->Int
minout=minoutaux 0
哪里
minoutaux::Int->[Int]->Int--\list base->最小整数>=列表中未出现基数
米努托碱[]=碱
minoutaux base[x]=base+(如果x==base,则为1,否则为0)
minoutaux base xs=if(长度smallpart==n2),则minoutaux(base+n2)bigpart else minoutaux base smallpart
哪里
n=(长度xs)
n2=n`div`2

smallpart=[x | xRichard Bird在他的书的第一章中描述了这个确切的问题(那一章恰好是亚马逊上的预览版)

这是如何在线性时间内运行的?我假设这是在多项式时间内运行的。在每次递归调用期间,整个列表在
length
smallpart
bigpart
中进行遍历。由于懒惰,在
smallpart
bigpart
中的遍历可能是线性的,但是
length
呢?我应该这样做haps之前已经详细解释了这一点。谢谢你指出这一点,我编辑了答案并添加了解释。