zoukankan      html  css  js  c++  java
  • 0074. Search a 2D Matrix (M)

    Search a 2D Matrix (M)

    题目

    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.

    Example 1:

    Input:
    matrix = [
      [1,   3,  5,  7],
      [10, 11, 16, 20],
      [23, 30, 34, 50]
    ]
    target = 3
    Output: true
    

    Example 2:

    Input:
    matrix = [
      [1,   3,  5,  7],
      [10, 11, 16, 20],
      [23, 30, 34, 50]
    ]
    target = 13
    Output: false
    

    题意

    判断在一个行元素递增、列元素也递增的矩阵中能否找到目标值。

    思路

    有序序列中找值那肯定是要用二分法,不过可以有两种二分查找的方式:

    1. 先一个二分找到目标值应该在的行,再一个二分在该行中查找目标值。
    2. 由于矩阵的特殊性(行递增,且下一行元素都比上一行元素大),可以将矩阵直接当成长度为 m*n 的一维数组处理。
    3. 分治法,从左下角开始搜索,target更大则向右走,target更小则向上走(该题里实际就是暴力遍历)。

    代码实现

    Java

    矩阵二分

    class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            int m = matrix.length;
            if (m == 0) return false;
            int n = matrix[0].length;
            if (n == 0) return false;
    
            if (target < matrix[0][0]) {
                return false;
            }
    
            // 先找行
            int left = 0, right = m - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                if (target < matrix[mid][0]) {
                    right = mid - 1;
                } else if (target > matrix[mid][0]) {
                    left = mid + 1;
                } else {
                    return true;
                }
            }
            int r = left - 1;
    
            // 再找列
            left = 0;
            right = n - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                if (target < matrix[r][mid]) {
                    right = mid - 1;
                } else if (target > matrix[r][mid]) {
                    left = mid + 1;
                } else {
                    return true;
                }
            }
            
            return false;
        }
    }
    

    一维二分

    class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            int m = matrix.length;
            if (m == 0) return false;
            int n = matrix[0].length;
            if (n == 0) return false;
    
            int left = 0, right = m * n - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                // 一维坐标转换为二维坐标
                int x = mid / n;
                int y = mid % n;
                if (target < matrix[x][y]) {
                    right = mid - 1;
                } else if (target > matrix[x][y]) {
                    left = mid + 1;
                } else {
                    return true;
                }
            }
            return false;
        }
    }
    

    JavaScript

    矩阵二分

    /**
     * @param {number[][]} matrix
     * @param {number} target
     * @return {boolean}
     */
    var searchMatrix = function (matrix, target) {
      if (matrix.length === 0 || matrix[0].length === 0) {
        return false
      }
    
      let m = matrix.length
      let n = matrix[0].length
    
      let left = 0
      let right = m - 1
    
      while (left <= right) {
        let mid = Math.trunc((right - left) / 2) + left
        if (matrix[mid][0] < target) {
          left = mid + 1
        } else if (matrix[mid][0] > target) {
          right = mid - 1
        } else {
          return true
        }
      }
    
      if (right >= 0) {
        let row = right
        left = 0
        right = n - 1
    
        while (left <= right) {
          let mid = Math.trunc((right - left) / 2) + left
          if (matrix[row][mid] < target) {
            left = mid + 1
          } else if (matrix[row][mid] > target) {
            right = mid - 1
          } else {
            return true
          }
        }
      }
    
      return false
    }
    

    分治法

    /**
     * @param {number[][]} matrix
     * @param {number} target
     * @return {boolean}
     */
    var searchMatrix = function (matrix, target) {
      if (matrix.length === 0 || matrix[0].length === 0) {
        return false
      }
    
      let m = matrix.length, n = matrix[0].length
      let i = m - 1, j = 0
    
      while (i >= 0 && j < n) {
        if (matrix[i][j] < target) {
          j++
        } else if (matrix[i][j] > target) {
          i--
        } else {
          return true
        }
      }
    
      return false
    }
    
  • 相关阅读:
    Atom 和 markdown 基本使用
    c++11 正则表达式基本使用
    Emacs 之窗口管理
    Emacs 之列编辑模式
    Emacs 之查看帮助
    使用 json_in_java
    Linux服务 httpd
    Linux 编译安装BIND
    Kerberos
    Linux服务 DNS&BIND
  • 原文地址:https://www.cnblogs.com/mapoos/p/13826960.html
Copyright © 2011-2022 走看看