在一系列随机生成的布尔值中,改变' k'忠于真理,创造最大的连续的真理链

时间:2018-05-05 15:57:34

标签: algorithm

我在接受采访时被问到以下问题:

在一组随机生成的布尔值中,例如: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翻转。

这个问题的最佳算法是什么?

非常感谢。

2 个答案:

答案 0 :(得分:4)

查找包含k个false值的最大范围。您可以通过保持运行窗口在线性时间内完成此操作。

答案 1 :(得分:1)

你真的可以用滑动窗口来做到这一点。我实际上认为,即使从概念上讲它并不是一个难题,但要使边缘案例的索引正确,特别是在面试的压力下,这是很棘手的。

以下是一种方法:

将两个索引变量设置为零(startend)。在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;
&#13;
&#13;