给定一组跳过的数字,我需要找到集合中不存在的第N个数字.例:
给定[1,4,5]一些结果:
对于N = 1结果0
对于N = 2结果2(因为跳过1)
对于N = 3结果3(因为跳过1)
对于N = 4结果6(因为1,4,5被跳过)
这应该适用于相当大的N,所以直截了当的解决方案并没有完全削减它=(
一种方法是构建一个辅助数组,告诉您,对于数组中的每个索引,它下面缺少值的数量.例如,在这个数组中:
1 4 5 9 13 (Array A)
Run Code Online (Sandbox Code Playgroud)
这个数组将是
1 4 5 9 13 (Array A)
1 3 3 6 9 (Array B)
Run Code Online (Sandbox Code Playgroud)
您可以使用以下方法在时间O(n)中填写数组B:
你现在可以做一个重要的观察:对于任何位置i,A [i]的值由B [i] + i给出.(在上面查看).为什么是这样?那么,对于任何位置i,其下方缺少的数字是B [i].在它之前还有i个数字,这意味着小于它的值的总数是B [i] + i.
现在您已经拥有了这个,您可以回答"什么是第k个丢失号码?"这一形式的查询.在时间O(log n)中使用以下算法:
例如,让我们采用早期的数组:
1 4 5 9 13 (Array A)
1 3 3 6 9 (Array B)
Run Code Online (Sandbox Code Playgroud)
假设我们想要第5个最小的缺失值.我们的二进制搜索找到了这个位置:
1 4 5 9 13 (Array A)
1 3 3 6 9 (Array B)
^
Run Code Online (Sandbox Code Playgroud)
备份一个位置需要我们:
1 4 5 9 13 (Array A)
1 3 3 6 9 (Array B)
^
Run Code Online (Sandbox Code Playgroud)
答案应该是A [i] + k - B [i] + 1.这是5 - 3 + 5 + 1 = 8.这是正确的:
让我们做另一个:假设我们想要第6个.二进制搜索将我们带到这里:
1 4 5 9 13 (Array A)
1 3 3 6 9 (Array B)
^
Run Code Online (Sandbox Code Playgroud)
备份一个地方:
1 4 5 9 13 (Array A)
1 3 3 6 9 (Array B)
^
Run Code Online (Sandbox Code Playgroud)
我们想要A [i] + k - B [i] + 1 = 9 + 6 - 6 + 1 = 10.这确实是正确的答案.
总的来说,这是O(n)预处理,并且查询可以在每个时间O(log n)中求解.
希望这可以帮助!