难度: 中等 | 标签: 查找

1. 题目描述

https://leetcode.cn/problems/search-a-2d-matrix-ii/
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

示例 1:
searchgrid2.jpg
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true
示例 2:
searchgrid.jpg
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= n, m <= 300
  • -109 <= matrix[i][j] <= 109
  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列
  • -109 <= target <= 109

通过次数: 269,421 | 提交次数: 527,443

2. 题解

2022-05-10 AC, 一开始想的二分查找, 倒是也能过, 效率不太行
效率的方式是从右上往左下查找

  1. <?php
  2. /**
  3. * Created by PhpStorm
  4. * User: jtahstu
  5. * Time: 2022/5/10 15:36
  6. * Des: 剑指 Offer 04. 二维数组中的查找
  7. * https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
  8. * 240. 搜索二维矩阵 II
  9. * https://leetcode.cn/problems/search-a-2d-matrix-ii/
  10. * 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
  11. */
  12. class Solution
  13. {
  14. /**
  15. * @param Integer[][] $matrix
  16. * @param Integer $target
  17. * @return Boolean
  18. */
  19. function findNumberIn2DArray($matrix, $target)
  20. {
  21. if (!$matrix || !count($matrix) || !count($matrix[0])) {
  22. return false;
  23. }
  24. $n = count($matrix);
  25. $m = count($matrix[0]);
  26. $i = 0;
  27. $j = $m - 1;
  28. while ($i < $n && $j >= 0) {
  29. $x = $matrix[$i][$j];
  30. if ($x == $target) {
  31. return true;
  32. } elseif ($x > $target) { //大于目标值往左
  33. $j--;
  34. } else { //小于目标值往下
  35. $i++;
  36. }
  37. }
  38. return false;
  39. /**
  40. * 执行用时:76 ms, 在所有 PHP 提交中击败了5.77%的用户
  41. * 内存消耗:24.7 MB, 在所有 PHP 提交中击败了69.23%的用户
  42. * 通过测试用例:129 / 129
  43. */
  44. /**
  45. * 下面自己想的解法, 速度竟然更快? 不敢相信
  46. * 执行用时:52 ms, 在所有 PHP 提交中击败了53.85%的用户
  47. * 内存消耗:25.1 MB, 在所有 PHP 提交中击败了5.77%的用户
  48. * 通过测试用例:129 / 129
  49. */
  50. }
  51. //自己想的, 不算快
  52. function findNumberIn2DArray2($matrix, $target)
  53. {
  54. $n = count($matrix);
  55. if ($n == 0) {
  56. return false;
  57. }
  58. $m = count($matrix[0]);
  59. if ($m == 0) {
  60. return false;
  61. }
  62. for ($i = 0; $i < $n; $i++) {
  63. if ($matrix[$i][0] > $target) {
  64. break;
  65. }
  66. $matrix[$i] = array_slice($matrix[$i], 0, $m);
  67. $row = $this->binary_search($matrix[$i], $target);
  68. // echo $row . PHP_EOL;
  69. // echo implode(" ", $matrix[$i]) . PHP_EOL;
  70. if ($row == PHP_INT_MAX) {
  71. return true;
  72. } else {
  73. $m = $row;
  74. }
  75. }
  76. return false;
  77. }
  78. function binary_search($nums, $target)
  79. {
  80. $l = 0;
  81. $r = count($nums) - 1;
  82. while ($l <= $r) {
  83. $mid = intval(($l + $r) / 2);
  84. $v = $nums[$mid];
  85. if ($target == $v) {
  86. return PHP_INT_MAX;
  87. }
  88. if ($v > $target) {
  89. $r = $mid - 1;
  90. }
  91. if ($v < $target) {
  92. $l = $mid + 1;
  93. }
  94. }
  95. return $l;
  96. }
  97. }
  98. $a = [
  99. [1, 4, 7, 11, 15],
  100. [2, 5, 8, 12, 19],
  101. [3, 6, 9, 16, 22],
  102. [10, 13, 14, 17, 24],
  103. [18, 21, 23, 26, 30]
  104. ];
  105. var_dump((new Solution)->findNumberIn2DArray($a, 16));
  106. var_dump((new Solution)->findNumberIn2DArray($a, 20));
  107. /**
  108. * 执行用时:48 ms, 在所有 PHP 提交中击败了88.16%的用户
  109. * 内存消耗:24.9 MB, 在所有 PHP 提交中击败了28.95%的用户
  110. * 通过测试用例:129 / 129
  111. */
  112. //原来是从右上往左下遍历呀, 没想到没想到
  113. //class Solution {
  114. // public boolean findNumberIn2DArray(int[][] matrix, int target) {
  115. // if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
  116. // return false;
  117. // }
  118. // int rows = matrix.length, columns = matrix[0].length;
  119. // int row = 0, column = columns - 1;
  120. // while (row < rows && column >= 0) {
  121. // int num = matrix[row][column];
  122. // if (num == target) {
  123. // return true;
  124. // } else if (num > target) {
  125. // column--;
  126. // } else {
  127. // row++;
  128. // }
  129. // }
  130. // return false;
  131. // }
  132. //}