每行二分
class Solution {
public int countNegatives(int[][] grid) {
int row=grid.length;
int col=grid[0].length;
int cot=0;
for(int i=0;i<row;i++){
if(grid[i][col-1]>=0) continue;
if(grid[i][0]<0){
cot+=col;
continue;
}//两个小剪枝
//二分要找到每行第一个>=0的数
int left=0;
int right=col-1;
while(left<=right){
int mid=left+(right-left)/2;
if(grid[i][mid]<0){
if(mid>=1&&grid[i][mid-1]>=0){
cot+=col-mid;
break;
}
if(mid>=1&&grid[i][mid-1]<0){
right=mid-1;
}
}else{
left=mid+1;
}
}
}
return cot;
}
}
看题解受启发,可以每次二分的时候,右边界可以参考上一行的mid。
如下面. 第一行的-5(mid),它后面的数全是负数,那么下一行的也是。
8下面的正负未知。此位置不能确定为二分的右边界
10 9 8 -5 -9
9 8 -5 -9 -10
class Solution {
public int countNegatives(int[][] grid) {
int row=grid.length;
int col=grid[0].length;
int cot=0;
int pox=col-1;
for(int i=0;i<row;i++){
if(grid[i][col-1]>=0) continue;
if(grid[i][0]<0){
cot+=col;
continue;
}
int left=0;
int right=pox;
while(left<=right){
int mid=left+(right-left)/2;
if(grid[i][mid]<0){
if(mid>=1&&grid[i][mid-1]>=0){
cot+=col-mid;
pox=mid;
break;
}
if(mid>=1&&grid[i][mid-1]<0){
right=mid-1;
}
}else{
left=mid+1;
}
}
}
return cot;
}
}