LC每日一题|20240409 - 2529. 正整数和负整数的最大计数

108 阅读2分钟

LC每日一题|20240409 - 2529. 正整数和负整数的最大计数

题目

给你一个按 非递减顺序 排列的数组 nums ,返回正整数数目和负整数数目中的最大值。

  • 换句话讲,如果 nums 中正整数的数目是 pos ,而负整数的数目是 neg ,返回 posneg二者中的最大值。

注意: 0 既不是正整数也不是负整数。

题目级别:Easy

提示:

  • 1 <= nums.length <= 2000
  • -2000 <= nums[i] <= 2000
  • nums非递减顺序 排列。

进阶: 你可以设计并实现时间复杂度为 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天了...

WechatIMG1315.jpg