leetcode
leetcode 2201 ~ 2250
正整数和负整数的最大计数

正整数和负整数的最大计数

难度:

标签:

题目描述

Given an array nums sorted in non-decreasing order, return the maximum between the number of positive integers and the number of negative integers.

  • In other words, if the number of positive integers in nums is pos and the number of negative integers is neg, then return the maximum of pos and neg.

Note that 0 is neither positive nor negative.

 

Example 1:

Input: nums = [-2,-1,-1,1,2,3]
Output: 3
Explanation: There are 3 positive integers and 3 negative integers. The maximum count among them is 3.

Example 2:

Input: nums = [-3,-2,-1,0,0,1,2]
Output: 3
Explanation: There are 2 positive integers and 3 negative integers. The maximum count among them is 3.

Example 3:

Input: nums = [5,20,66,1314]
Output: 4
Explanation: There are 4 positive integers and 0 negative integers. The maximum count among them is 4.

 

Constraints:

  • 1 <= nums.length <= 2000
  • -2000 <= nums[i] <= 2000
  • nums is sorted in a non-decreasing order.

 

Follow up: Can you solve the problem in O(log(n)) time complexity?

代码结果

运行时间: 25 ms, 内存: 16.2 MB


/*
 题目思路:
 使用Java Stream,我们可以通过filter和count方法来分别计算正整数和负整数的数量,最后返回二者中的较大值。
*/

import java.util.Arrays;

public class Solution {
    public int maximumCount(int[] nums) {
        long pos = Arrays.stream(nums).filter(num -> num > 0).count();
        long neg = Arrays.stream(nums).filter(num -> num < 0).count();
        return (int) Math.max(pos, neg);
    }
}

解释

方法:

此题解利用了二分查找方法,通过 Python 的 bisect 模块来高效地确定正数和负数的数量。由于数组已经按非递减顺序排列,可以使用 bisect_left 来查找第一个非负数(0或正数)的位置,这个位置也表示负数的数量。同理,使用 bisect_right 查找第一个大于0的位置,用数组长度减去这个位置得到正数的数量。最后,比较这两个数量,取最大值返回。

时间复杂度:

O(log n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在这个问题中选择使用二分查找来计算正负数的数量,而不是简单地遍历整个数组?
选择使用二分查找而不是遍历整个数组的原因是效率。二分查找适用于已排序的数组,并且其时间复杂度为O(log n),这比遍历数组的O(n)时间复杂度要低得多。在大数据量的情况下,二分查找可以显著减少计算时间。
🦆
在使用`bisect_left`查找第一个非负数的位置时,如何保证它确实指向了0而不是正数,尤其是在没有0的情况下?
`bisect_left(nums, 0)`函数会返回数组中第一个不小于0的元素的位置。如果数组中包含0,则它会指向第一个0;如果数组中不包含0,它会指向第一个正数。这个位置同时也是负数数量的计数,因为它表示了数组中从开始到这个位置之前所有的数都是负数。
🦆
在调用`bisect_right(nums, 0)`时,如果数组中包含一个或多个0,这会如何影响正数的计数?
`bisect_right(nums, 0)`函数会返回数组中第一个严格大于0的元素的位置。如果数组中包含一个或多个0,`bisect_right`将返回最后一个0之后的位置。这确保了所有的0都被包括在内,而计算正数的数量时,从这个位置开始到数组结束的所有元素都是正数。因此,这个位置用于确定正数的开始位置,从而正确计算正数的数量。
🦆
对于一个全是正数或全是负数的数组,这种方法处理的效率如何,有没有更高效的处理方式?
对于全是正数或全是负数的数组,这种方法仍然是效率的,因为二分查找在这种情况下也能迅速确定正数或负数的边界。例如,如果数组全是正数,`bisect_left(nums, 0)`将会返回0,`bisect_right(nums, 0)`也将返回0,从而快速确定没有负数。对于全是负数的数组,这两个函数将返回数组的长度和数组长度,从而确定没有正数。在这种特殊情况下,二分查找的效率与直接检查数组的第一个或最后一个元素的效率相当,因为二分查找迅速缩小了搜索范围。

相关问题