javascript - 如何有效地找到数组中所有先前索引加起来为给定整数 N 的数字的索引?
问题描述
更新:我意识到这个问题是无效的。忽略它。我在for
循环中犯了一个错误,实际上只需要大约 1 毫秒来对所有索引求和,而不是半秒,这导致我假设它可以使用二进制搜索进行优化,这不适用于这里。
假设我们有:
- 一个整数
target = 85
- 整数数组
array = [36, 48, 48, 36, 48, 48, 48, 48, 48, 48]
我们如何有效地找到index
at which sum(array[0], array[N]) > target
?在此示例中,索引将是2
因为索引的总和超过了target
at 索引2
。
基本上,我有一个元素的虚拟容器(它始终只呈现一小部分元素),所有这些元素都有不同的高度(36、48 等)和一个scroll
返回滚动像素数量(目标)的事件,所以我试图找到容器滚动到的元素,在这个例子中,容器向下滚动85px
,这意味着它滚动传递了元素2
。
例子:
let target = 85
let array = [36, 48, 48, 36, 48, 48, 48, 48, 48, 48]
// Finding the element with a bruteforce method:
array[0] > target // false
array[0] + array[1] > target // false
array[0] + array[1] + array[2] > target // true
return 2
由于某种原因,尝试使用sum
所有索引直到我们使用循环找到目标值for
每 1000 个值需要半秒。
我不确定是否已经有一个众所周知的算法,但我认为我必须使用二进制搜索的自定义衍生形式来在几次迭代中找到索引,例如:
Divide the array in half
Sum all the indexes in the left half
If the target < sum, it means the target is in the left half, so divide it again
If the target > sum, extend the search to the right half
Repeat recursively
我已经部分创建了这个递归算法,但是当目标位于数组的“右半部分”时,我很难弄清楚如何正确target > halfSliceSum
处理条件,即:
let target = 85
let array = [36, 48, 48, 36, 48, 48, 48, 48, 48, 48]
console.log(getElementIndexAtTargetPosition(array, target))
function getElementIndexAtTargetPosition(array, target) {
// TESTS (expected results):
// ([36, 48, 48, 36, 48, 48, 48, 48, 48, 48], 35) => return 0
// ([36, 48, 48, 36, 48, 48, 48, 48, 48, 48], 36) => return 0
// ([36, 48, 48, 36, 48, 48, 48, 48, 48, 48], 37) => return 1
// ([36, 48, 48, 36, 48, 48, 48, 48, 48, 48], 84) => return 1
// ([36, 48, 48, 36, 48, 48, 48, 48, 48, 48], 85) => return 2
// ([36, 48, 48, 36, 48, 48, 48, 48, 48, 48], 456) => return 8
let halfIndex = Math.round(array.length / 2)
let halfSlice = array.slice(0, halfIndex)
let halfSliceSum = halfSlice.reduce((a, b) => a + b, 0)
if (array.length === 1) {
return 0
}
if (target === halfSliceSum) {
return halfIndex
}
else if (target < halfSliceSum) {
return getElementIndexAtTargetPosition(halfSlice, target)
}
else if (target > halfSliceSum) {
// Increase search slice by Math.round(halfIndex * 1.5)?
// ...
}
}
目标始终在数组内,即target <= sum(array[0], array[lastIndex])
解决方案
您必须将所有单独的值相加,直到达到阈值,当您刚刚获得数组时,没有其他方法可以做到这一点。
但是,如果您必须多次执行此操作,它可以帮助将数组转换为递增和之一,然后您可以在其上运行二进制搜索(假设没有负求和因此它实际上是递增序列)。您甚至可以删除原始数组,因为您仍然可以通过计算差异来访问其值。
推荐阅读
- python - 在两个值之间切换变量的最pythonic方法
- linq - 如何检索与连接实体关联的两个实体,仅在名称 record2roleid 下?
- c++ - 如何使用 C++ 和 OpenCV 从视频中删除 16x16 像素帧?
- docker - 删除/覆盖主机或容器中的挂载文件
- javascript - 为下拉选项分配多个值
- c++ - 调试语句的 C++ 预处理器
- python - 在 azure 注册表中运行的 docker 容器中从 celery 将 blob 上传到存储帐户时出错
- java - 声纳错误报告删除这个总是评估为“真”的表达式
- java - Swing 我如何允许用户选择的主题?
- xcode - 为什么每次我尝试将动画链接到 SpriteNode 时 xcode 都会崩溃?