矩阵寻找目标值的技巧

抛开对知识、学问的依赖心理,是你走上人生康庄大道的关键。

本篇文章所涉及的算法题:


在这里插入图片描述

1. 解题技巧

  1. 首先区分 矩阵方阵

  2. 定义行(Row)和列(Column):

    • rows = matrix.length;
    • cols = martrix[0].length;
  3. 矩阵的遍历

    for(int i = 0;i < rows;i++){
          
          
    	for(int j = 0; j < cols;j++){
          
          
    		// TODO ![在这里插入图片描述](https://img-blog.csdnimg.cn/487fae0eddd34646b2fa2ff950412335.webp#pic_center)
    
    	}
    }
    

2. 案例

本篇文章主要用来讨论总结一下处理矩阵中查找目标元素的方案。

240. 搜索二维矩阵 II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。

该矩阵具有以下特性:

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

如图所示:
在这里插入图片描述

1. 解法

利用题目中矩阵的特点,选中左上角作为起始点来遍历。

时间复杂度:O(m+n)

public boolean searchMatrix(int[][] matrix, int target) {
    
    
        // 1. 处理边界
        if(matrix == null || matrix.length == 0){
    
    
            return false;
        }
		// 处理矩阵题目的好规范:优先把行数、列数给统计出来
        int rows = matrix.length;
        int cols = matrix[0].length;
		
		// 选用『左上角』为起始点
        int i = 0;
        int j = cols-1;

        while(i < rows && j >= 0){
    
    
            if(matrix[i][j] == target){
    
    
                return true;
            }

            if(matrix[i][j] < target){
    
    
                i++;
            }else{
    
    
                j--;
            }
        }
        return false;
    }

74. 搜索二维矩阵

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

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

PS: 注意此题与 240. 搜索二维矩阵 II的区别。
此题展开是一个有序的一维数组

1. 解法一(O(m+n))

上面的解法依然可以解决此题

public boolean searchMatrix(int[][] matrix, int target) {
    
    
        if(matrix == null || matrix.length == 0){
    
    
            return false;
        }

        int rows = matrix.length;
        int cols = matrix[0].length;

        int i = 0;
        int j = cols- 1;

        while(i < rows && j >= 0){
    
    
            if(matrix[i][j] == target){
    
    
                return true;
            }

            if(matrix[i][j] > target){
    
    
                j--;
            }else{
    
    
                i++;
            }
        }
        return false;
    }
2. 解法二(O(log(m) + log(n)) - 最优解

初中知识都没忘吧 :log(m) + log(n) = log(mn)
根据题目的描述,可以得出该矩阵展开为一个递增有序的一维数组
聪明的你一定知道,看到有序,就要联想到二分法(BinarySearch)

 public boolean searchMatrix(int[][] matrix, int target) {
    
    
        // 将二维数组看作是一维的
        if(matrix == null || matrix.length == 0){
    
    
            return false;
        }

        int rows = matrix.length;
        int cols = matrix[0].length;

        int left = 0;
        int right = rows * cols - 1;

        while(left <= right){
    
    
            int mid = left + (right-left)/2;

            // 核心:根据mid在一维数组中的位置 推导出其在矩阵中的位置。
            int i = mid / cols;
            int j = mid % cols;

            if(matrix[i][j] == target){
    
    
                return true;
            }

            if(matrix[i][j] < target){
    
    
                left = mid + 1;
            }else{
    
    
                right = mid - 1;
            }
        }

        return false;
    }
1351. 统计有序矩阵中的负数

给你一个 m * n 的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。
请你统计并返回 grid 中 负数 的数目。

如下图所示:
在这里插入图片描述

此题依然选择从左上角作为出发点,因为如果如果第一行的某一列小于0,则可以得出整列都是小于0的。

解法
 public int countNegatives(int[][] grid) {
    
    
        if(grid == null || grid.length == 0){
    
    
            return 0;
        }
        int rows = grid.length;
        int cols = grid[0].length;

        int i = 0;
        int j = cols-1;

        int result = 0;

        while(i < rows && j >= 0){
    
    
            if(grid[i][j] < 0){
    
    
                result+=(rows-i);
                j--;
            }else{
    
    
                i++;
            }
        }
        return result;
    }

猜你喜欢

转载自blog.csdn.net/wangcheeng/article/details/124638890