二分查找 
      
    
      
      
      
        数组 
      
    
      
      
      
        计数 
      
    
   
  
    
      
       
     
  
  
    
      
    
    
      
       
     
  
    
题目描述 
给你一个按 非递减顺序  排列的数组 nums ,返回正整数数目和负整数数目中的最大值。
    换句话讲,如果 nums 中正整数的数目是 pos ,而负整数的数目是 neg ,返回 pos 和 neg二者中的最大值。 
 
注意: 0 既不是正整数也不是负整数。
 
示例 1: 
输入: nums = [-2,-1,-1,1,2,3]
输出: 3
解释: 共有 3 个正整数和 3 个负整数。计数得到的最大值是 3 。
 
示例 2: 
输入: nums = [-3,-2,-1,0,0,1,2]
输出: 3
解释: 共有 2 个正整数和 3 个负整数。计数得到的最大值是 3 。
 
示例 3: 
输入: nums = [5,20,66,1314]
输出: 4
解释: 共有 4 个正整数和 0 个负整数。计数得到的最大值是 4 。
 
 
提示: 
    1 <= nums.length <= 2000 
    -2000 <= nums[i] <= 2000 
    nums 按 非递减顺序  排列。 
 
 
进阶: 你可以设计并实现时间复杂度为 O(log(n)) 的算法解决此问题吗?
解法 
方法一:遍历 
我们可以直接遍历数组,统计正整数和负整数的个数 \(a\)  和 \(b\) ,返回 \(a\)  和 \(b\)  中的较大值即可。
时间复杂度 \(O(n)\) ,其中 \(n\)  为数组长度。空间复杂度 \(O(1)\) 。
Python3 Java C++ Go TypeScript Rust C 
class   Solution : 
    def   maximumCount ( self ,  nums :  List [ int ])  ->  int : 
        a  =  sum ( x  >  0  for  x  in  nums ) 
        b  =  sum ( x  <  0  for  x  in  nums ) 
        return  max ( a ,  b ) 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 class  Solution   { 
     public   int   maximumCount ( int []   nums )   { 
         int   a   =   0 ,   b   =   0 ; 
         for   ( int   x   :   nums )   { 
             if   ( x   >   0 )   { 
                 ++ a ; 
             }   else   if   ( x   <   0 )   { 
                 ++ b ; 
             } 
         } 
         return   Math . max ( a ,   b ); 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 class   Solution   { 
public : 
     int   maximumCount ( vector < int >&   nums )   { 
         int   a   =   0 ,   b   =   0 ; 
         for   ( int   x   :   nums )   { 
             if   ( x   >   0 )   { 
                 ++ a ; 
             }   else   if   ( x   <   0 )   { 
                 ++ b ; 
             } 
         } 
         return   max ( a ,   b ); 
     } 
}; 
 
 
func   maximumCount ( nums   [] int )   int   { 
     var   a ,   b   int 
     for   _ ,   x   :=   range   nums   { 
         if   x   >   0   { 
             a ++ 
         }   else   if   x   <   0   { 
             b ++ 
         } 
     } 
     return   max ( a ,   b ) 
} 
 
 
function   maximumCount ( nums :   number []) :   number   { 
     let   [ a ,   b ]   =   [ 0 ,   0 ]; 
     for   ( const   x   of   nums )   { 
         if   ( x   >   0 )   { 
             ++ a ; 
         }   else   if   ( x   <   0 )   { 
             ++ b ; 
         } 
     } 
     return   Math . max ( a ,   b ); 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 impl   Solution   { 
     pub   fn   maximum_count ( nums :   Vec < i32 > )   ->   i32   { 
         let   mut   a   =   0 ; 
         let   mut   b   =   0 ; 
         for   x   in   nums   { 
             if   x   >   0   { 
                 a   +=   1 ; 
             }   else   if   x   <   0   { 
                 b   +=   1 ; 
             } 
         } 
         std :: cmp :: max ( a ,   b ) 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 #define max(a, b) (a > b ? a : b) 
int   maximumCount ( int *   nums ,   int   numsSize )   { 
     int   a   =   0 ,   b   =   0 ; 
     for   ( int   i   =   0 ;   i   <   numsSize ;   ++ i )   { 
         if   ( nums [ i ]   >   0 )   { 
             ++ a ; 
         }   else   if   ( nums [ i ]   <   0 )   { 
             ++ b ; 
         } 
     } 
     return   max ( a ,   b ); 
} 
 
 
 
 
方法二:二分查找 
由于数组是按非递减顺序排列的,因此可以使用二分查找找到第一个大于等于 \(1\)  的元素的下标 \(i\)  以及第一个大于等于 \(0\)  的元素的下标 \(j\) ,那么正整数的个数 \(a = n - i\) ,负整数的个数 \(b = j\) ,返回 \(a\)  和 \(b\)  中的较大值即可。
时间复杂度 \(O(\log n)\) ,其中 \(n\)  为数组长度。空间复杂度 \(O(1)\) 。
Python3 Java C++ Go TypeScript Rust C 
class   Solution : 
    def   maximumCount ( self ,  nums :  List [ int ])  ->  int : 
        a  =  len ( nums )  -  bisect_left ( nums ,  1 ) 
        b  =  bisect_left ( nums ,  0 ) 
        return  max ( a ,  b ) 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 class  Solution   { 
     public   int   maximumCount ( int []   nums )   { 
         int   a   =   nums . length   -   search ( nums ,   1 ); 
         int   b   =   search ( nums ,   0 ); 
         return   Math . max ( a ,   b ); 
     } 
     private   int   search ( int []   nums ,   int   x )   { 
         int   left   =   0 ,   right   =   nums . length ; 
         while   ( left   <   right )   { 
             int   mid   =   ( left   +   right )   >>   1 ; 
             if   ( nums [ mid ]   >=   x )   { 
                 right   =   mid ; 
             }   else   { 
                 left   =   mid   +   1 ; 
             } 
         } 
         return   left ; 
     } 
} 
 
 
class   Solution   { 
public : 
     int   maximumCount ( vector < int >&   nums )   { 
         int   a   =   nums . end ()   -   lower_bound ( nums . begin (),   nums . end (),   1 ); 
         int   b   =   lower_bound ( nums . begin (),   nums . end (),   0 )   -   nums . begin (); 
         return   max ( a ,   b ); 
     } 
}; 
 
 
func   maximumCount ( nums   [] int )   int   { 
     a   :=   len ( nums )   -   sort . SearchInts ( nums ,   1 ) 
     b   :=   sort . SearchInts ( nums ,   0 ) 
     return   max ( a ,   b ) 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 function   maximumCount ( nums :   number []) :   number   { 
     const   search   =   ( x :   number ) :   number   =>   { 
         let   [ left ,   right ]   =   [ 0 ,   nums . length ]; 
         while   ( left   <   right )   { 
             const   mid   =   ( left   +   right )   >>   1 ; 
             if   ( nums [ mid ]   >=   x )   { 
                 right   =   mid ; 
             }   else   { 
                 left   =   mid   +   1 ; 
             } 
         } 
         return   left ; 
     }; 
     const   i   =   search ( 1 ); 
     const   j   =   search ( 0 ); 
     const   [ a ,   b ]   =   [ nums . length   -   i ,   j ]; 
     return   Math . max ( a ,   b ); 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 impl   Solution   { 
     fn   search ( nums :   & Vec < i32 > ,   x :   i32 )   ->   usize   { 
         let   mut   left   =   0 ; 
         let   mut   right   =   nums . len (); 
         while   left   <   right   { 
             let   mid   =   ( left   +   right )   >>   1 ; 
             if   nums [ mid ]   >=   x   { 
                 right   =   mid ; 
             }   else   { 
                 left   =   mid   +   1 ; 
             } 
         } 
         left 
     } 
     pub   fn   maximum_count ( nums :   Vec < i32 > )   ->   i32   { 
         let   n   =   nums . len (); 
         let   i   =   Self :: search ( & nums ,   1 ); 
         let   j   =   Self :: search ( & nums ,   0 ); 
         ( n   -   i ). max ( j )   as   i32 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 #define max(a, b) (a > b ? a : b) 
int   search ( int *   nums ,   int   numsSize ,   int   x )   { 
     int   left   =   0 ; 
     int   right   =   numsSize ; 
     while   ( left   <   right )   { 
         int   mid   =   ( left   +   right )   >>   1 ; 
         if   ( nums [ mid ]   >=   x )   { 
             right   =   mid ; 
         }   else   { 
             left   =   mid   +   1 ; 
         } 
     } 
     return   left ; 
} 
int   maximumCount ( int *   nums ,   int   numsSize )   { 
     int   i   =   search ( nums ,   numsSize ,   1 ); 
     int   j   =   search ( nums ,   numsSize ,   0 ); 
     return   max ( numsSize   -   i ,   j ); 
}