LeetCode 题解工作台

统计得分小于 K 的子数组数目

一个数组的 分数 定义为数组之和 乘以 数组的长度。 比方说, [1, 2, 3, 4, 5] 的分数为 (1 + 2 + 3 + 4 + 5) * 5 = 75 。 给你一个正整数数组 nums 和一个整数 k ,请你返回 nums 中分数 严格小于 k 的 非空整数子数组数目 。 子数组 是数组…

category

4

题型

code_blocks

6

代码语言

hub

3

相关题

当前训练重点

困难 · 二分·搜索·答案·空间

bolt

答案摘要

我们先计算出数组 的前缀和数组 ,其中 表示数组 前 个元素的和。 接下来,我们枚举数组 每个元素作为子数组的最后一个元素,对于每个元素,我们可以通过二分查找的方式找到最大的长度 ,使得 $s[i] - s[i - l] \times l < k$。那么以该元素为最后一个元素的子数组个数即为 ,我们将所有的 相加即为答案。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

一个数组的 分数 定义为数组之和 乘以 数组的长度。

  • 比方说,[1, 2, 3, 4, 5] 的分数为 (1 + 2 + 3 + 4 + 5) * 5 = 75 。

给你一个正整数数组 nums 和一个整数 k ,请你返回 nums 中分数 严格小于 k 的 非空整数子数组数目

子数组 是数组中的一个连续元素序列。

 

示例 1:

输入:nums = [2,1,4,3,5], k = 10
输出:6
解释:
有 6 个子数组的分数小于 10 :
- [2] 分数为 2 * 1 = 2 。
- [1] 分数为 1 * 1 = 1 。
- [4] 分数为 4 * 1 = 4 。
- [3] 分数为 3 * 1 = 3 。 
- [5] 分数为 5 * 1 = 5 。
- [2,1] 分数为 (2 + 1) * 2 = 6 。
注意,子数组 [1,4] 和 [4,3,5] 不符合要求,因为它们的分数分别为 10 和 36,但我们要求子数组的分数严格小于 10 。

示例 2:

输入:nums = [1,1,1], k = 5
输出:5
解释:
除了 [1,1,1] 以外每个子数组分数都小于 5 。
[1,1,1] 分数为 (1 + 1 + 1) * 3 = 9 ,大于 5 。
所以总共有 5 个子数组得分小于 5 。

 

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105
  • 1 <= k <= 1015
lightbulb

解题思路

方法一:前缀和 + 二分查找

我们先计算出数组 nums\textit{nums} 的前缀和数组 ss,其中 s[i]s[i] 表示数组 nums\textit{nums}ii 个元素的和。

接下来,我们枚举数组 nums\textit{nums} 每个元素作为子数组的最后一个元素,对于每个元素,我们可以通过二分查找的方式找到最大的长度 ll,使得 s[i]s[il]×l<ks[i] - s[i - l] \times l < k。那么以该元素为最后一个元素的子数组个数即为 ll,我们将所有的 ll 相加即为答案。

时间复杂度 O(n×logn)O(n \times \log n),空间复杂度 O(n)O(n)。其中 nn 为数组 nums\textit{nums} 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution:
    def countSubarrays(self, nums: List[int], k: int) -> int:
        s = list(accumulate(nums, initial=0))
        ans = 0
        for i in range(1, len(s)):
            l, r = 0, i
            while l < r:
                mid = (l + r + 1) >> 1
                if (s[i] - s[i - mid]) * mid < k:
                    l = mid
                else:
                    r = mid - 1
            ans += l
        return ans
speed

复杂度分析

指标
时间complexity is O(n) because each element is processed at most twice in the sliding window. Space complexity is O(1) additional space beyond the input array if prefix sums are maintained in place.
空间O(1)
psychology

面试官常问的追问

外企场景
  • question_mark

    Look for binary search usage on the maximum valid length to see if the candidate recognizes the answer-space pattern.

  • question_mark

    Observe if the candidate optimizes with sliding window rather than brute-force O(n^2) subarray enumeration.

  • question_mark

    Check for careful handling of single-element subarrays and edge score thresholds to avoid off-by-one mistakes.

warning

常见陷阱

外企场景
  • error

    Brute-force enumeration of all subarrays leads to TLE for large arrays; always consider binary search or prefix sum optimization.

  • error

    Failing to account for single-element subarrays can cause undercounting.

  • error

    Incorrectly updating sum or length in sliding window may miscount subarrays crossing the threshold exactly at k.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Count subarrays with sum less than k ignoring the length multiplier.

  • arrow_right_alt

    Find maximum length subarray with score less than k instead of counting all.

  • arrow_right_alt

    Return subarrays themselves rather than counts, applying the same binary search check.

help

常见问题

外企场景

统计得分小于 K 的子数组数目题解:二分·搜索·答案·空间 | LeetCode #2302 困难