1351. 统计有序矩阵中的负数『简单』

题目来源于力扣(LeetCode

一、题目

1351. 统计有序矩阵中的负数

题目相关标签:数组、二分查找

说明:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 100
  • -100 <= grid[i][j] <= 100

二、解题思路

2.1 线性扫描法

  1. 据题意:矩阵元素无论是按行还是按列,都以非递增顺序排列

  2. 遍历矩阵,再每次遍历一个一维数组

  3. 判断当前一维数组中的元素是否为负数

  4. 为负数时,即其后的元素也必定为负数,则该数组中负数的个数为数组长度 - 当前索引

  5. 结束当前一维数组的遍历

2.2 二分查找法

  1. 遍历矩阵,每次遍历一个一维数组

  2. 对一维数组进行二分查找的操作

  3. 如二分计算得到的中间索引,其在一维数组上的元素大于等于 0 时,左指针等于中间索引加 1,继续在缩小后的范围中查找第一个负数出现索引位

  4. 中间索引上的元素为负数时,右指针等于中间索引减 1,继续在缩小后的范围中查找第一个负数出现索引位

  5. 循环结束后,最后的左指针索引位一定是指向第一个负数的所在索引,则该数组中的负数个数等于数组长度 - 左指针所在索引

三、代码实现

3.1 线性扫描法

public static int countNegatives(int[][] grid) {
    int ans = 0;
    for (int i = 0; i < grid.length; i++) {
        for (int j = 0; j < grid[i].length; j++) {
            // 当前遍历元素为负数时,则索引后的元素也必定为负数(非递增数组)
            if (grid[i][j] < 0) {
                ans += grid[i].length - j;
                // 结束当前矩阵行的遍历,开始下一行矩阵数组的遍历
                break;
            }
        }
    }
    return ans;
}

3.2 二分查找法

public static int countNegatives(int[][] grid) {
    int ans = 0;
    for (int i = 0; i < grid.length; i++) {
        int[] arr = grid[i];
        int left = 0;
        int right = arr.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            // 中间索引上的值大于等于 0 时,向右边缩小范围
            if (arr[mid] >= 0) {
                left = mid + 1;
            } else {
                // 中间索引上的值小于 0 时,向左边缩小范围,判断前边元素是否也小于 0
                right = mid - 1;
            }
        }
        // 最后 left 索引所在的位置即是第一个负数所在的索引(其之后的元素也是负数)
        // 数组中负数个数 = 数组长度 - left 索引
        ans += arr.length - left;
    }
    return ans;
}

四、执行用时

4.1 线性扫描法

4.2 二分查找法

五、部分测试用例

public static void main(String[] args) {
    int[][] grid = {{4, 3, 2, -1}, {3, 2, 1, -1}, {1, 1, -1, -2}, {-1, -1, -2, -3}};  // output:8
//    int[][] grid = {{3, 2}, {1, 0}};  // output:0
//    int[][] grid = {{1, -1}, {-1, -1}};  // output:3
//    int[][] grid = {{-1}};  // output:1
    
    int result = countNegatives(grid);
    System.out.println(result);
}
posted @ 2020-05-28 21:51  知音12138  阅读(416)  评论(0编辑  收藏  举报