数组右上角不回退遍历模型 查找元素、查找最多的1

102 阅读1分钟

题目

给定一个元秦为非负整数的二維数组matrix,每行和每列都是从小到大有序的。再给定一个非负整数aim,请判新aim是否在matrix中。

  • 从数组右上角开始遍历,因为该点是当前行最大,当前列最小,target 若不等于右上角点,则一定在能够排除一列或一行,也就是说比当前节点小的一定在左边,比当前节点大的一定在下面,按照这个不会回退的规律,最终遍历时间复杂度能从 O(n*m) 变成 O(n+m)

image.png

function process(arr, target) {
  const y = arr.length;
  const x = arr[0].length;

  let i = x - 1,
    j = 0;

  while (i < x && i > 0 && j > 0 && j < x - 1) {
    if (target !== arr[i][j]) {
      // 每次只往一个方向遍历
      if (target > arr[i][j]) {
        j++;
      } else {
        i--;
      }
    } else {
      return true;
    }
  }

  return false;
}

题目

查询数组中1最多的行,其中1只会在最右边,0只会在最左边

  • 从右上角顶点开始从右往左遍历,如果是1统计个数,如果遇到0开始往下遍历,如果下方还是1,则从下方1开始往右遍历统计,如果是0则直接跳过。同样是通过不会回退的遍历,将时间复杂度从O(n*m)变成O(n+m)

image.png

function process(arr) {
  let maxLine = 0,
    maxNum = 0,
    tempNum,
    i = 0;
  let y = arr.length,
    x = arr[0].length - 1;

  while (i < y && x > 0) {
    if (arr[i][x] === 1) {
      x--;
      tempNum = maxNum++;
    } else if (arr[i][x] === 0) {
      if (tempNum > maxNum) {
        maxNum = tempNum;
        maxLine = i;
        tempNum = 0;
      }
      i++;
    }
  }

  return maxLine;
}