LC每日一题|20240409 - 2529. 正整数和负整数的最大计数
题目
给你一个按 非递减顺序 排列的数组
nums,返回正整数数目和负整数数目中的最大值。
- 换句话讲,如果
nums中正整数的数目是pos,而负整数的数目是neg,返回pos和neg二者中的最大值。注意:
0既不是正整数也不是负整数。
题目级别:Easy
提示:
1 <= nums.length <= 2000-2000 <= nums[i] <= 2000nums按 非递减顺序 排列。
进阶: 你可以设计并实现时间复杂度为 O(log(n)) 的算法解决此问题吗?
解法
如果不看进阶要求的话,这是妥妥的翻译题,上代码吧~
class Solution {
fun maximumCount(nums: IntArray): Int {
var z = 0
var f = 0
nums.forEach {
if (it > 0) z++
if (it < 0) f++
}
return Math.max(z, f)
}
}
时间复杂度O(n),遍历一遍直接就解决问题了~
进阶
卡了时间复杂度到O(logN),结合加粗的非递减数组5个大字,就差把二分写脸上了...
不过,u1s1,虽然我前前后后也刷了差不多400题了,但二分一直是我心中的痛...
因为我是真tm不会写二分TAT
具体二分要找啥,这个方案可就多了去了,但含义是差不多的,比如:
找到第一个大于等于0的数 & 找到第一个大于等于1的数
- 第一个大于等于0的数左侧一定是负数,所以该数的下标就等于负数的数量
- 第一个大于等于1的数一定是正数的开始
class Solution {
fun maximumCount(nums: IntArray): Int {
val f = bs(nums, 0)
val z = nums.size - bs(nums, 1)
return Math.max(f, z)
}
fun bs(nums: IntArray, target: Int): Int {
var left = 0
var right = nums.size - 1
while (left <= right) {
val mid = (left + right) / 2
if (nums[mid] >= target) right = mid - 1 else left = mid + 1
}
return left
}
}
碎碎念
今天的面试很失败,感觉自己的状态还是没有调整好...
原来2023已经离开我们100天了...