遍历(预生成数组) 牛牛染色方块

77 阅读2分钟

题目

牛牛有一些排成一行的正方形。每个正方形已经被染成红色或者绿色。牛牛现在可以选择任意一个正方形然后用这两种颜色的任意一种进行染色,这个正方形的颜色将会被覆盖。牛牛的目标是在完成染色之后,每个红色R都比每个绿色G距离最左侧近。牛牛想知道他最少需要涂染几个正方形。如样例所示:S =RGRGR我们涂染之后变成RRRGG满足要求了,涂染的个数为2.没有比这个更好的涂染方案。

  • 遍历规则为从左边零位开始,左边全染为R,右边全染为G,遍历到下一位依次类推,然后比较出最少的方式
function process(arr) {
  const len = arr.length;
  const count = 0;
  const min = Infinity;
  for (let i = 0; i < len; i++) {
    // 右边全染为G
    if (i === 0) {
      for (let j = 0; j < len; j++) {
        if (arr[j] === "R") {
          count++;
        }
      }
    } else if (i === len - 1) {
      // 全为R的情况
      for (let j = 0; j < len; j++) {
        if (arr[i] === "G") {
          count++;
        }
      }
    } else {
      // 左边为R、右边为G的所有情况
      for (let j = 0; j <= i; j++) {
        if (arr[i] === "G") {
          count++;
        }
      }
      for (let j = i + 1; j < len; j++) {
        if (arr[i] === "R") {
          count++;
        }
      }
    }

    if (count < min) {
      min = count;
    }
  }

  return min;
}

  • 优化:预处理数组技巧,将0-i范围上所有的G、R数量先查询出来
function process(arr) {
  const len = arr.length;
  const count = 0;
  const min = Infinity;
  const arrG,arrR=[];
  
  for (let i = 0; i < len; i++) {
    if(arr[i]==="G"){
       if(arrG[i-1]!==0){
           arrG[i]=arrG[i-1]+1
       }else{
           arrG[i]=1
       }
    }else{
       if(arrR[i-1]!==0){
           arrR[i]=arrR[i-1]+1
       }else{
           arrR[i]=1
       }
    }
  }
  for (let i = 0; i < len; i++) {
    // 右边全染为G
    if (i === 0) {
      count=arrR[len-1];
    } else if (i === len - 1) {
      // 全为R的情况
      count=arrG[len-1];
    } else {
      // 左边为R、右边为G的所有情况
      count=arrG[i]+arrR[len-1]-arrR[i+1]
    }

    if (count < min) {
      min = count;
    }
  }

  return min;
}