我有一个100位的位模式。程序会将模式中的位更改为true或false。在任何给定的时间,我需要找到第一个“n”真值的位置。例如,如果模式如下
10011001000
位为真的前3个索引是0,3,4 位为真的前4个索引是0,3,4,7
我可以有一个List,但firstntrue(int)的复杂性将是O(n)。无论如何都要提高性能?
答案 0 :(得分:3)
我假设您在搜索时列表没有变化,但是在您决定搜索之前它会发生变化,然后您就会进行搜索。
对于每个字节,有2 ^ 8 = 256个0和1的组合。这里有100/8 = 13个字节要检查。
因此,您可以构建256个条目的查找表。关键是您在比特流中检查的字节的当前实际值,该值是您搜索的数据(包含1位位置的元组)。所以,如果你给它5,它将返回{0,2}。这种查找的成本是恒定的,内存使用量非常小。
现在,当您浏览比特流时,您可以一次处理一个字节(而不是一次一个字节),并且只跟踪当前字节数(当然从0开始)并添加8 * current-byte-number为返回的元组中的值。所以现在你已经通过使用预先计算的查找表将问题简化为O(n / 8)。
您可以构建一个更大的查找表以获得更快的速度,但这会占用更多内存。
虽然我无法想象n = 100的O(n)算法确实是一些性能问题的根源。除非你在内部循环中调用了很多东西?
答案 1 :(得分:1)
没有办法改善O(n)。这可以用数学证明
答案 2 :(得分:0)
没有
好吧,除非你在发生变化时拦截变化,否则保持“前100个”列表。
答案 3 :(得分:0)
如果没有其他数据结构,复杂性就无法降低,因为在最坏的情况下,您需要扫描整个列表。
答案 4 :(得分:0)
对于“n”项,您最多需要检查“n”次.E O(n)!
你怎么能期望在没有任何拦截的情况下减少它并且知道它们如何改变?!
答案 5 :(得分:0)
不,如果你只有一个普通的阵列,就无法提高复杂性。
如果1:s到很多0:s你可以通过常数因子改善性能,但它仍然是O(n)。
如果您可以将位数组视为字节数组(甚至是int32数组),则可以检查每个字节是否为字节>检查每个位之前为0。
如果1位比1:8少,则可以将其实现为稀疏数组而不是List<byte>
,其中存储所有1:s的索引。
答案 6 :(得分:0)
正如其他人所说,在没有其他结构的情况下找到n个最低设置位是O(n)操作。
如果您希望提高性能,请查看问题的实现方面吗?
脱离我的头顶,q&amp; 〜(q-1)将只留下数字q中设置的最低位,因为从任何二进制数中减去1会向右填充1s直到设置的第一个数字,将该数字更改为0并保留其余数字单独。在设置为1位的数字中,向右移动并对零进行测试给出了一个简单的测试,以区分潜在答案是否小于实际答案或大于或等于。所以你可以从那里进行二分搜索。
要查找下一个数字,请删除最低位并使用较小的初始二进制搜索窗口。可能有更好的解决方案,但这应该比从最小到最大的每一点都要好,并检查它是否已设置。
这种实现不会影响复杂性的东西,但可能有助于提高性能。