74. Search a 2D Matrix

Use binary search. Don't treat it as a 2D matrix, just treat it as a sorted array:
m * n matrix convert to an array => matrix[x][y] => a[x * n + y]
an array convert to m **n matrix => a[x] =>matrix[x / n][x % n];

/*
74. Search a 2D Matrix 
Total Accepted: 74543 Total Submissions: 222239 Difficulty: Medium
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
Given target = 3, return true.

Hide Tags Array Binary Search
Hide Similar Problems (M) Search a 2D Matrix II
*/
import java.util.*;

public class SearchMatrix {
    public static void main(String[] args) {
        int[][] matrix1 = { {1,   3,  5,  7}, {10, 11, 16, 20}, {23, 30, 34, 50}};
        int[][] matrix2 =  {{1}, {3}};
        int[][] matrix3 = {{-5}};
        int target = 3;
    
        System.out.println(searchMatrix(matrix1, target) == true ?
            " Test case 1 success" : " Test case 1 failed");
        System.out.println(searchMatrix(matrix2, target) == true ?
            " Test case 2 success" : " Test case 2 failed");
        System.out.println(searchMatrix(matrix3, target) == false ? 
            " Test case 3 success" : " Test case 3 failed");
    }
    
    public static boolean searchMatrix(int[][] matrix, int target) {
        /*
            Use binary search.  Don't treat it as a 2D matrix, just treat it as a sorted array
            m * n matrix convert to an array => matrix[x][y] => a[x * n + y]
            an array convert to m * n matrix => a[x] =>matrix[x / n][x % n];
            https://leetcode.com/discuss/15379/binary-search-on-an-ordered-matrix
            https://leetcode.com/discuss/10735/dont-treat-it-as-a-2d-matrix-just-treat-it-as-a-sorted-list
            */
            int m = matrix.length, n = matrix[0].length;
        int begin = 0, end = m * n - 1;
        
        while (begin <= end) {
            int mid = begin + (end - begin)/2 ;
            int mid_val = matrix[mid / n][mid % n];
            if (mid_val == target) {
                return true;
            } else if (mid_val < target) {
                //Should move a bit further, otherwise dead loop.
                begin = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        return false;
    }
        
        
    // pass case 1 and 2, failed at case 3
    public static boolean searchMatrix_mine(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int rowUp = 0, rowDown = m-1, colLeft = 0, colRight = n-1;
        
        while(rowUp  <= rowDown ) {
            int mid = rowUp + (rowDown - rowUp)/2;
            int mid_val = matrix[rowUp][0] + (matrix[rowDown][n-1] - matrix[rowUp][0])/2;
            //System.out.printf("mid_val = %d ", mid_val);

            if (target == mid_val) {
                rowUp = mid;
                rowDown = mid;
                break;
            }
            else if (target > mid_val) {
                rowUp = mid + 1;
            } else {
                rowDown = mid -1;
            } 
           
        }
        
        while (colLeft <= colRight) {
            int mid = colLeft + (colRight - colLeft)/2;
            // System.out.printf("rowUp = %d, rowDown= %d \n", rowUp, rowDown);  
            // rowUp=1 , ArrayIndexOutOfBoundsException,  matrix[0][0] = -5 for case 3s
            //System.out.printf("colLeft = %d, colRight= %d\n", colLeft, colRight);
            int mid_val = matrix[rowUp][colLeft] + (matrix[rowUp][colRight] - matrix[rowUp][colLeft])/2;
            //System.out.printf("mid_val = %d\n", mid_val);
            if (target == mid_val ) return true;
            else if (target >  mid_val) {
                colLeft = mid + 1;
                System.out.printf("colLeft = %d, colRight= %d\n", colLeft, colRight);
            } else {
                colRight = mid ;
            }
            //System.out.printf("colLeft = %d, colRight= %d\n", colLeft, colRight);
        }
        return false;
    }
}

Javascript 解法 5/19/2019

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function(matrix, target) {
  //把这个数组当做一维数组处理,二分查找
  // [0, m*n - 1]
    if (matrix == '' || matrix == [])  return false;
    
    let m = matrix.length;
    let n = matrix[0].length;
    var start = 0;
    var end = m * n - 1;
    while (start <= end) {
        var mIdx = parseInt(start + (end - start) /2 );  // js 注意取整
        
        var median = matrix[parseInt(mIdx / n)][parseInt(mIdx % n)];
        if (median === target) return true;
        if (median < target) start = mIdx + 1;
        else end = mIdx - 1;
    }
    return false;
};

Reference

https://leetcode.com/discuss/15379/binary-search-on-an-ordered-matrix

https://leetcode.com/discuss/10735/dont-treat-it-as-a-2d-matrix-just-treat-it-as-a-sorted-list

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,776评论 0 33
  • https://leetcode.com/problems/search-a-2d-matrix/#/descri...
    Double_E阅读 137评论 0 0
  • 1、 感赏女儿善于听取别人的合理建议: 昨天女儿和我说今天要去清凉峰玩,因为这几天天气太热,最高温度都在40度左右...
    青青田园阅读 170评论 0 4
  • 基本任务 中秋节的前一天,SAE突然接到一个电话,有这么一个客户,他们专门给银行、基金公司提供营销服务,这回他们服...
    conglei_kobe阅读 22,676评论 5 30
  • 每天都是踏着0点的钟声走进家门,不得不说,这是一场灾难。 今天上午按照节奏一步一步的走着,下午就整个人都不好了,关...
    小无相功阅读 439评论 0 1