几周前有人在这里发布了这个问题,但它看起来非常像没有事先研究的家庭作业,OP在获得一些反对票后立即删除了它。
不过,这个问题本身很有趣,我已经想了一个星期,没有找到令人满意的解决方案。希望有人能帮忙?
问题如下:给定一个N个整数间隔的列表,其边界可以取从0
到N³
的任何值,找到最小的整数i
使得i
不属于任何输入间隔。
例如,如果给定列表(N=4),则算法应返回9。
我能想到的最简单的解决方案运行在O(n log(n))中,它包括三个步骤:
这个简单的解决方案运行在O(n log(n))中,但最初的海报写道,算法应该运行在O(n)中。如果已经对间隔进行了排序,那么这很简单,但OP给出的示例包括未排序的间隔。我想这一定与N³有关,但我不确定是什么。。。散列?线性时间排序?欢迎提出想法。
以下是上述算法的粗略python实现:
def merge(first, second):
(a, b), (c, d) = first, second
if c <= b + 1:
return (a, max(b, d))
else:
return False
def smallest_available_integer(intervals):
# Sort in reverse order so that push/pop operations are fast
intervals.sort(reverse = True)
if (intervals == [] or intervals[-1][0] > 0):
return 0
while len(intervals) > 1:
first = intervals.pop()
second = intervals.pop()
merged = merge(first, second)
if merged:
print("Merged", first, "with", second, " -> ", merged)
intervals.append(merged)
else:
print(first, "cannot be merged with", second)
return first[1] + 1
print(smallest_available_integer([(3,5), (2,8), (0,3), (10,13)]))
输出:
Merged (0, 3) with (2, 8) -> (0, 8)
Merged (0, 8) with (3, 5) -> (0, 8)
(0, 8) cannot be merged with (10, 13)
9
另一个想法是以某种方式使用这些间隔的补码。假设C()为您提供了一个区间的补码,例如C([3,5])将是小于3和大于5的整数。如果最大值为N^3,那么使用模N^3 1,甚至可以将其表示为另一个间隔[6,(N^3 1)2]。
如果您想要一个不属于任何原始区间的数字,那么这些区间的所有补码中都应该存在相同的数字。然后,它归结为编写一个函数,可以计算任何两个这样的“补码区间”的交点。
我还没有实现这个想法,因为我的纸笔图纸表明,在计算这样的交集时需要考虑的情况比我最初想象的要多。但我认为这背后的想法是有效的,它会导致O(n)算法。
编辑
经过进一步思考,有一个最坏的情况,使事情比我原先想象的更复杂。
详细说明@mrip的评论:您可以在O(n)时间内使用您描述的精确算法,但更改排序算法的工作方式。
通常,基数排序使用基数2:根据元素的位是0还是1将元素分成两个不同的桶。每轮基数排序需要时间O(n),并且每位有一轮最大的数字。调用最大的nunber U,这意味着时间复杂度为O(n log U)。
但是,您可以将基数排序的基数更改为其他基数。使用基b,每一轮都需要时间O(nb),因为初始化和迭代bucket需要时间O(b),将元素分配到bucket需要时间O(n)。然后是对数b轮。这给出了O的运行时间((n b)logbU)。
这里的诀窍是,由于最大数字U=n3,您可以设置b=n并使用基数n排序。现在轮数为lognU=lognn3,每轮需要O(n)个时间,因此对数字进行排序的总工作量为O(n)。更一般地说,对于任意k,可以在时间O(kn)内对[0,nk]范围内的数字进行排序。如果k是固定常数,则这是O(n)时间。
结合原始算法,这在时间O(n)内解决了问题。
希望这有帮助!
[2,30],[25,39],[30,40]溶胶[2,30]
我试图找出一种算法来寻找二部图的最小顶点覆盖。 我在考虑一个解决方案,将问题简化为二部图中的最大匹配。众所周知,可以使用从bip创建的networ中的最大流量来找到它。图表 最大匹配M应该决定最小。顶点覆盖C,但我无法处理选择要设置C的顶点。假设bip。图有部分X、Y,作为最大匹配边endpoint的顶点在集合A中,那些不属于B的顶点。 我会说,我应该为M到C中的边选择一个顶点。特别是M中的边e的
我正在使用Spring Boot 2.1.6.RELEASE,我想知道应该如何使用? 配置示例: 和位于不同的模块中。 错误: 无法注册在类路径资源[com/example/autoconf/configuration/app configuration . class]中定义的bean“foo”。已在类路径资源[com/my/configuration/myautoconfiguration .
程序屏幕截图 我正在制作动画。当我按下按钮时,它会触发一个动画,使从右侧浮动。当鼠标离开时JPanel退出动画),但问题是我在动画上有一个。因此,当我将鼠标移出动画时,面板不仅会消失,而且当我在按钮(这是面板的一个组件)上移动鼠标时,面板也会消失,这意味着当我想单击按钮时,它会消失,因为当鼠标离开时,就会被触发。 请看上面的图片,我在其中标记了某些区域。 < li >是JPanel,当我将鼠标移到
我正在尝试以下练习来提高我的在线技能,我遇到了以下问题。 这是一个演示任务。 编写一个函数:class Solution{public int Solutions(int[]A);},给定一个包含N个整数的数组A,返回A中没有出现的最小正整数(大于0)。 举个例子, 给定 A = [1, 3, 6, 4, 1, 2],函数应返回 5。给定 A = [1, 2, 3],函数应返回 4。给定 A =
在笛卡尔坐标中,我有一个知道高度h、宽度w和4个角(x, y)的矩形。如果我有一些值r,即圆的固定半径,如何计算将完全覆盖矩形的最小数量的圆的中心点?