Skip to content

Commit 0697726

Browse files
committed
1351 solved
1 parent 6763132 commit 0697726

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed
Binary file not shown.
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# 1351. 统计有序矩阵中的负数
2+
3+
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
4+
>
5+
> 同步博客:https://www.algomooc.com
6+
7+
题目来源于 LeetCode 上 1531 题。
8+
9+
## 题目
10+
11+
给你一个 m * n 的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 
12+
13+
请你统计并返回 grid 中 负数 的数目。
14+
15+
16+
示例 1:
17+
18+
19+
```
20+
输入:grid = [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]]
21+
输出:8
22+
解释:矩阵中共有 8 个负数。
23+
24+
```
25+
26+
示例 2:
27+
28+
```
29+
输入:grid = [[3,2],[1,0]]
30+
输出:0
31+
```
32+
33+
示例 3:
34+
35+
```
36+
输入:grid = [[1,-1],[-1,-1]]
37+
输出:3
38+
```
39+
40+
示例 4:
41+
42+
43+
```
44+
输入:grid = [[-1]]
45+
输出:1
46+
47+
```
48+
49+
50+
提示:
51+
52+
53+
m == grid.length
54+
55+
n == grid[i].length
56+
57+
1 <= m, n <= 100
58+
59+
-100 <= grid[i][j] <= 100
60+
61+
62+
## 题目解析
63+
64+
首先审题,在一个矩阵中找出所有负数,这个很好理解,小白一开始做,可以直接暴力遍历,然后依次判断当前值是不是小于0,小于0计数加一。如果是面试的话,面试官一般都会问还没有其他办法,这时候你肯定要说怎么没有,所以我们做一道题不能仅仅限于做出了,要从多方面下手,使得复杂度越小越好。
65+
66+
所以我们要仔细审题,我们看到题目中有这样一句描述**矩阵中的元素无论是按行还是按列,都以非递增顺序排列**,这句话信息量很大,你品,你仔细品。
67+
68+
首先我们可以理解到的是:一个 m * n 的矩阵 grid,grid[i][j]<0的话,i那一行第j个到数组最后一个都是小于0,第i行开始,j到后面的列都是小于0
69+
70+
我们举个例子
71+
72+
```
73+
[
74+
[4, 3, -1, -1],
75+
[3, 2, -1, -1],
76+
[1, 1, -1, -2],
77+
[-1, -1, -2, -3]
78+
]
79+
80+
```
81+
82+
可以看到第一行第三列的值小于0,那么第一行及后面几行的第三列和后面的列的值都小于0。
83+
84+
所以我们可以进行倒序遍历,找到负数的左边界,也就是左边第一个为负数的值。
85+
86+
i为行遍历的指针,j为列遍历指针,count为负数的个数,len1为**当前行**的个数,len2为**当前列**的个数
87+
88+
```
89+
初始值
90+
let count = 0;
91+
let len1 = grid.length
92+
let len2 = grid[0].length
93+
let i = 0;
94+
let j = len2 - 1;
95+
```
96+
97+
然后我们倒序遍历列,行还是正序遍历,以上面的例子来说,我们找到的第一个负数是grid[0][2],然后我们能确定的负数就有如下,所以我们count就可以加上(len1 - i -1) * (len2 - j )
98+
99+
```
100+
[
101+
[ -1, -1],
102+
[ -1, -1],
103+
[ -1, -2],
104+
[ -2, -3]
105+
]
106+
107+
```
108+
109+
然后我们遍历的矩阵就变成如下,然后重复上面操作。
110+
111+
112+
```
113+
[
114+
[3, 2],
115+
[1, 1],
116+
[-1, -1]
117+
]
118+
119+
```
120+
121+
所以我们每次遍历后要更新len1和len2,具体看代码和动画。
122+
123+
124+
## 动画理解
125+
126+
127+
<video id="video" controls="" preload="none" >
128+
<source id="mp4" src="../Animation/1351.mp4" type="video/mp4">
129+
</video>
130+
131+
## 参考代码
132+
133+
```JavaScript
134+
/**
135+
* @param {number[][]} arr
136+
* @return {number}
137+
*/
138+
var countNegatives = function(arr) {
139+
if (arr.length <= 0 ) {return 0}
140+
let count = 0;
141+
let len1 = arr.length;
142+
let len2 = arr[0].length;
143+
let i = 0;
144+
let j = len2 - 1;
145+
while(i < len1) {
146+
while(j >= 0) {
147+
if (arr[i][j] < 0) {
148+
if (j==0){
149+
count += (len2 * (len1 - i))
150+
len2 = 0
151+
break
152+
}
153+
j--
154+
}else {
155+
if (len2 == j + 1) {
156+
break
157+
}
158+
count += ((len2 - j - 1) * (len1 - i))
159+
len2 = j + 1
160+
break
161+
}
162+
}
163+
i++
164+
j= len2 - 1
165+
}
166+
return count
167+
};
168+
```
169+
170+
## 复杂度分析
171+
172+
时间复杂度: O(m)。
173+
174+
空间复杂度:O(1)。
175+
176+
177+
![](../../Pictures/qrcode.jpg)

0 commit comments

Comments
 (0)