Day3.二维数组搜索

594 阅读2分钟

题目

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

我的解法

思路

从左上角开始,向右/向下都是递增的。用循环来写。

循环条件:数组没有溢出并且当前的值小于目标值

  1. 选择当前值
  2. 比较当前值与目标值
  3. 决定下一步往哪里走,或者是找到
    • 当前值和目标值相同,下一步不用移动
    • 右边的值比较小,下一步向右走
    • 下边的值比较小,下一步向下走
    • 到边界,只往一个方向走

问题:

  1. 可能出现右边的值比较小,但下边的值是目标值的情况
  2. 可能出现右边的值比较小,但目标值的下边的下边的情况

解决:

  1. 加上条件判断,“右边的值比较小&&下边的值不是目标值,下一步向右走”
  2. 无法解决,该算法本身有问题

代码:

function find(target, array) {
  debugger
  const row = array.length
  const col = array[0].length
  let rp = 0
  let cp = 0
  if (row === 0 || col === 0) {
    return false
  } else if (array[0][0] > target || array[row - 1][col - 1] < target) {
    return false
  } else {
    while (rp < row && cp < col && array[rp][cp] <= target) {
      // 当array[rp][cp]没有溢出并且小于目标值循环
      if (array[rp][cp] === target) {
        return true
      } else if (rp + 1 === row) {
        // 如果到最后一行了,每次只增加列数
        cp++
      } else if (cp + 1 === col) {
        // 如果到最后一列了,每次只增加行数
        rp++
      } else if (array[rp + 1][cp] <= array[rp][cp + 1] && array[rp][cp + 1] !== target) {
        // 往增量小的方向移动,并且另一个方向不是目标结果
        rp++
      } else {
        cp++
      }
    }
    return false
  }
}

正确解法

思路

从数组的最右上角开始,如果目标值小于当前值,下一步向右;如果目标值大于当前值,下一步向下。

  1. 初始化要选择的位置
  2. 循环条件:要选择的位置没有发生溢出
  3. 取当前值
  4. 比较当前值和目标值
    • 如果相同,返回
    • 目标值大于当前值,向下走
    • 目标值小于当前值,向左走

分析

跟上面的算法思路很类似,每移动一步相当于删去了一行/一列(向下移动删去了一行,向左移动删去了一列),但是上面的算法没有办法保证删去的那一行/一列中一定不存在目标值。

而这种算法类似于二分查找,目标值大于当前值,比当前值小的都可以舍去;目标值小于当前值,比当前值大的都可以舍去。

实现

function find(array, target) {
  const row = array.length
  const col = array[0].length
  let rp = 0
  let cp = col - 1
  let current
  while (rp < row && cp >= 0) {
    current = array[rp][cp]
    if (current === target) {
      return true
    } else if (current < target) {
      rp++
    } else {
      cp--
    }
  }
  return false
}

总结

while循环的思路

  1. 初始化选择条件
  2. 判断循环条件
  3. 根据选择条件选择初始化的值
  4. 分支语句修改选择条件

所以代码是这样的格式

初始化选择条件
while(){
	**选择**
	if(){
    	修改选择条件
    } else if() {
    	修改选择条件
    } else {
    	return
    }

}
return