每行二分
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;
}
}