我在接受采访时被问到以下问题:
在一组随机生成的布尔值中,例如:T F T T F F F F F F F F
编写算法以确定哪些错误值更改为true,以最大化最大连续的trues块。在上面的例子中,假设k = 3.其中一个解决方案是:
T F T T T* T* T* T F F F F T
其中T *表示已更改的值。
除了简单的暴力之外,我提出的方法之一是找到最大的连续False值块,并将其与k进行比较。如果它更少,那么我们用True替换整个块并继续使用' k'剩下的就是。然而,事实证明这种方法并不能始终保证正确答案。
我想到的另一个更复杂的方法是这样:对于块之间的每一块谬误,计算通过在真实之间翻转谬误来构建大块的块。然后,它归结为选择最佳组合块之间的trues翻转。
这个问题的最佳算法是什么?
非常感谢。
答案 0 :(得分:4)
查找包含k个false值的最大范围。您可以通过保持运行窗口在线性时间内完成此操作。
答案 1 :(得分:1)
你真的可以用滑动窗口来做到这一点。我实际上认为,即使从概念上讲它并不是一个难题,但要使边缘案例的索引正确,特别是在面试的压力下,这是很棘手的。
以下是一种方法:
将两个索引变量设置为零(start
和end
)。在k + 1' F'之前向前扫描end
。 (或数组的结尾)将' F的索引放在一个数组中。这是您最初的猜测和F&C的定位。
将end
增加到下一个' F',并将start
移动到F位置数组中的下一个索引。测试它是否更长并重复。您可以跟踪最好的start
,这将是最初的' F'你需要改变。
展示示例比解释更容易,但它基本上是一个移动的窗口,同时跟踪最佳运行和最佳初始' F' F' F' F' F' F' F' F' F' F'改变。这是一个快速而又脏的JS实现:
function findBestFlips(k, arr) {
let start, end, max, best_start, n;
start = end = max = best_start_index = n = 0;
let fs = [];
for (end = 0; end <= arr.length; end++) {
if (arr[end] == 0) {
fs.push(end)
if (fs.length <= k + 1) {
max = end; // set initial max from start of array to right before (k+1)th false value
continue // fill up fs with k+1 values if possible
}
if (max < (end - (fs[start] + 1))) {
max = end - (fs[start] + 1)
best_start_index = start + 1
}
start++
}
}
/* The above while loop stopped with potentially more ‘T’s at the end of the array.
push on to the end of the array */
if (max < arr.length - (fs[start] + 1)) {
max = arr.length - (fs[start] + 1)
best_start_index = start + 1
}
/* fs should have the index of all the false values
best_start through k + best_start_index are the indexes we need to change
to get the best_run */
if (fs.length <= k) max = arr.length
return {
flip_indexes: fs.slice(best_start_index, k + best_start_index),
best_run: max
}
}
let arr = [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
let k = 3;
console.log(findBestFlips(k, arr))
// edge cases
arr = [1, 0, 1, 1, 1, 1]
k = 3;
console.log(findBestFlips(k, arr))
arr = [0, 0, 0]
k = 3;
console.log(findBestFlips(k, arr))
arr = [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0]
k = 3;
console.log(findBestFlips(k, arr))
&#13;