【LeetCode】搜索二维矩阵Java题解 | Java刷题打卡

213 阅读1分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接

题目描述

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。

示例 1:

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/search-a-2d-matrix

思路分析

  • 这个题目题意容易理解,有多种方法可以解决。
  • 首先可以采用 HashMap 的方式以空间换时间高效查找解决。缺点是没有利用题目提示的矩阵特征。
  • 也可以采取两次二分查找,同时利用矩阵特点,提升查询效率。优点是无需额外空间,查询效率高。

AC代码

  • HashMap 解法
public class DayCode {
    public static void main(String[] args) {
        int[][] matrix = {{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 60}};
        int target = 3;
        boolean ans = new DayCode().searchMatrix(matrix, target);
        System.out.println(ans);
    }


    /**
     * 时间复杂度 O (m * n)
     * 空间复杂度 O (m * n)
     * @param matrix
     * @param target
     * @return
     */
    public boolean searchMatrix(int[][] matrix, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int row = 0; row < matrix.length; row++) {
            for (int col = 0; col < matrix[row].length; col++) {
                map.put(matrix[row][col], matrix[row][col]);
            }
        }

        return map.containsKey(target);
    }
}
  • 二分查找方法
public class DayCode {
    public static void main(String[] args) {
        int[][] matrix = {{1, 3, 5, 7}, {10, 11, 16, 20}, {23, 30, 34, 60}};
        int target = 3;
        boolean ans1 = new DayCode().searchMatrix1(matrix, target);
        System.out.println(ans1);
    }

    /**
     * 时间复杂度 O(log (m + n))
     * 空间复杂度 O(1)
     * @param matrix
     * @param target
     * @return
     */
    public boolean searchMatrix1(int[][] matrix, int target) {
        int rowIdx = binarySearchFirstColumn(matrix, target);
        if (rowIdx < 0) {
            return false;
        }
        return binarySearchRow(matrix[rowIdx], target);
    }

    private boolean binarySearchRow(int[] matrix, int target) {
        int left = 0, right = matrix.length - 1;
        while (left <= right) {
            int mid = (right - left) / 2 + left;
            if (matrix[mid] == target) {
                return true;
            } else if (matrix[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return false;
    }

    private int binarySearchFirstColumn(int[][] matrix, int target) {
        int low = -1, high = matrix.length - 1;
        while (low < high) {
            int mid = (high - low + 1) / 2 + low;
            if (matrix[mid][0] <= target) {
                low = mid;
            } else {
                high = mid - 1;
            }
        }
        return  low;
    }

}

提交测试:

image.png

总结

  • HashMap 解法的时间复杂度 O (m * n),空间复杂度 O (m * n)
  • 二分查找 解法的时间复杂度 O(log (m + n)),空间复杂度 O(1)
  • 坚持每日一题,加油!