以前的65字节解决方案:
r->{for(int a,b=0,z,i=0;;b=a)if((a=b|1<<(z=r[i++]))==b)return z;}
新的解决方案。包含19个字节import java.math.*;
-8个字节,感谢@Nevay
r->{int z,i=0;for(BigInteger c=BigInteger.ZERO;c.min(c=c.setBit(z=r[i++]))!=c;);return z;}
在线尝试!
编辑
我原始程序中的算法很好,但是使用的数据类型的静态大小意味着一旦大小超过某个阈值,它就会很快崩溃。
我已经更改了计算中使用的数据类型,以增加程序的内存限制以适应此限制(使用BigInteger
任意精度代替int
或long
)。但是,这是否可算作O(1)
空间复杂性值得商bat 。
我将完整地保留我的解释,但我想补充一点,我现在认为如果O(1)
不作一些假设就不可能实现空间的复杂性。
证明
定义N
为这样的整数2 <= N
。
设S
一个表示一系列随机整数的列表[x{1}, ..., x{N}]
,其中x{i}
有约束1 <= x{i} <= N
。
每个元素精确遍历此列表所需的时间复杂度(用Big-O表示)为 O(n)
面临的挑战是在列表中找到第一个重复的值。更具体地说,我们正在搜索第一个值,S
因为它是列表中上一个项目的重复项。
令p
和q
为列表中两个元素的位置,使得p < q
和x{p} == x{q}
。我们面临的挑战是找到q
满足这些条件的最小产品。
解决此问题的明显方法是遍历S并检查我们是否x{i}
存在于另一个列表中T
:如果x{i}
不存在T
,则将其存储在中T
。如果x{i}
确实存在T
,则它是第一个重复值,因此是最小的q
,因此我们将其返回。这个空间效率是O(n)
。
为了O(1)
在保持O(n)
时间复杂度的同时实现空间复杂度,我们必须在有限的空间中存储有关列表中每个对象的唯一信息。因此,任何算法都能在O(1)
空间复杂度是:1.给N上限值,该上限值对应于存储特定有限数据类型的最大可能值数量所需的内存。2.对单个不可变变量的重新分配不计入复杂性,仅计入变量数(列表为多个变量)。3.(基于其他答案)列表是可变的(或至少是列表的元素是可变的),并且列表的数据类型预设为有符号整数,从而允许对列表中其他元素进行更改无需使用额外的内存。
1和3都需要有关数据类型的假设和规范,而2则只需要考虑变量数量来计算空间复杂度,而不要考虑这些变量的大小。如果这些假设都不被接受,那么将不可能同时实现O(n)
时间复杂度和O(1)
空间复杂度。
说明
哇,这个男孩花了一个令人尴尬的长时间思考了一下脑力。
因此,争取奖金是困难的。我们既需要整个列表恰好一次上操作和跟踪其价值我们已经迭代,而无需额外的空间复杂度。
位操作解决了这些问题。我们初始化我们的O(1)
“存储”(一对整数),然后遍历列表,对第一个整数中的第i个位进行或运算,然后将结果存储到第二个中。
例如,如果我们有1101
,并且我们使用进行“或”运算10
,我们将得到1111
。如果我们再做一次OR 10
,我们仍然有1101
。
如此,一旦我们执行“或”运算并以相同的数字结尾,便找到了重复项。数组中没有重复项将导致程序运行并引发异常。