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

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

难度简单

给你一个 m * n 的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 

请你统计并返回 grid 中 负数 的数目。

 

示例 1:

输入:grid = [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]]
输出:8
解释:矩阵中共有 8 个负数。

示例 2:

输入:grid = [[3,2],[1,0]]
输出:0

示例 3:

输入:grid = [[1,-1],[-1,-1]]
输出:3

示例 4:

输入:grid = [[-1]]
输出:1

 

提示:

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

 

进阶:你可以设计一个时间复杂度为 O(n + m) 的解决方案吗?

可以使用二分法,来寻找每一行中的小于0的第一个数,他后面的数字必定都小于0,直接统计求和。复杂度为n * ln(m);

进阶版需要 O(n + m),需要从左上角到右下角遍历,先往左遍历,遇到第一个为大于0的,则统计其后面的数字的个数,在往下一行遍历。

    public int countNegatives(int[][] grid) {
        int count = 0;
        int a = grid.length;
        int b = grid[0].length;
        int end = b - 1;
        for (int i = 0; i < a; i++) {
            int[] ints = grid[i];
            int value = find(ints, 0, end);
            if (ints[value] < 0) {
                count += (b - value);
                end = value - 1;
            } else {
                count += (b - value - 1);
                end = value;
            }
        }
        return count;
    }

    private int find(int[] arr, int st, int end) {
        while (st < end) {
            int m = st + ((end - st) >> 1);
            if (arr[m] < 0) {
                end = m;
            } else {
                st = m  + 1;
            }
        }
        return st;
    }

 

posted @ 2021-05-23 13:47  旺仔古李  阅读(98)  评论(0编辑  收藏  举报