数组
二分查找
计数
题目描述
给你一个按 非递减顺序 排列的数组 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 );
}