Skip to content

feat: add solutions to lc problem: No.2302 #4344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 129 additions & 34 deletions solution/2300-2399/2302.Count Subarrays With Score Less Than K/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ tags:

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

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

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

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

<!-- tabs:start -->

Expand All @@ -93,14 +93,14 @@ class Solution:
s = list(accumulate(nums, initial=0))
ans = 0
for i in range(1, len(s)):
left, right = 0, i
while left < right:
mid = (left + right + 1) >> 1
l, r = 0, i
while l < r:
mid = (l + r + 1) >> 1
if (s[i] - s[i - mid]) * mid < k:
left = mid
l = mid
else:
right = mid - 1
ans += left
r = mid - 1
ans += l
return ans
```

Expand All @@ -116,16 +116,16 @@ class Solution {
}
long ans = 0;
for (int i = 1; i <= n; ++i) {
int left = 0, right = i;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = i;
while (l < r) {
int mid = (l + r + 1) >> 1;
if ((s[i] - s[i - mid]) * mid < k) {
left = mid;
l = mid;
} else {
right = mid - 1;
r = mid - 1;
}
}
ans += left;
ans += l;
}
return ans;
}
Expand All @@ -146,16 +146,16 @@ public:
}
long long ans = 0;
for (int i = 1; i <= n; ++i) {
int left = 0, right = i;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = i;
while (l < r) {
int mid = (l + r + 1) >> 1;
if ((s[i] - s[i - mid]) * mid < k) {
left = mid;
l = mid;
} else {
right = mid - 1;
r = mid - 1;
}
}
ans += left;
ans += l;
}
return ans;
}
Expand All @@ -168,25 +168,81 @@ public:
func countSubarrays(nums []int, k int64) (ans int64) {
n := len(nums)
s := make([]int64, n+1)
for i, v := range nums {
s[i+1] = s[i] + int64(v)
for i, x := range nums {
s[i+1] = s[i] + int64(x)
}
for i := 1; i <= n; i++ {
left, right := 0, i
for left < right {
mid := (left + right + 1) >> 1
l, r := 0, i
for l < r {
mid := (l + r + 1) >> 1
if (s[i]-s[i-mid])*int64(mid) < k {
left = mid
l = mid
} else {
right = mid - 1
r = mid - 1
}
}
ans += int64(left)
ans += int64(l)
}
return
}
```

#### TypeScript

```ts
function countSubarrays(nums: number[], k: number): number {
const n = nums.length;
const s: number[] = Array(n + 1).fill(0);
for (let i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}
let ans = 0;
for (let i = 1; i <= n; ++i) {
let [l, r] = [0, i];
while (l < r) {
const mid = (l + r + 1) >> 1;
if ((s[i] - s[i - mid]) * mid < k) {
l = mid;
} else {
r = mid - 1;
}
}
ans += l;
}
return ans;
}
```

#### Rust

```rust
impl Solution {
pub fn count_subarrays(nums: Vec<i32>, k: i64) -> i64 {
let n = nums.len();
let mut s = vec![0i64; n + 1];
for i in 0..n {
s[i + 1] = s[i] + nums[i] as i64;
}
let mut ans = 0i64;
for i in 1..=n {
let mut l = 0;
let mut r = i;
while l < r {
let mid = (l + r + 1) / 2;
let sum = s[i] - s[i - mid];
if sum * (mid as i64) < k {
l = mid;
} else {
r = mid - 1;
}
}
ans += l as i64;
}
ans
}
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand All @@ -197,7 +253,7 @@ func countSubarrays(nums []int, k int64) (ans int64) {

我们可以使用双指针的方式,维护一个滑动窗口,使得窗口内的元素和小于 $k$。那么以当前元素为最后一个元素的子数组个数即为窗口的长度,我们将所有的窗口长度相加即为答案。

时间复杂度 $O(n)$,其中 $n$ 为数组 $nums$ 的长度。空间复杂度 $O(1)$。
时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -207,8 +263,8 @@ func countSubarrays(nums []int, k int64) (ans int64) {
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
ans = s = j = 0
for i, v in enumerate(nums):
s += v
for i, x in enumerate(nums):
s += x
while s * (i - j + 1) >= k:
s -= nums[j]
j += 1
Expand Down Expand Up @@ -258,8 +314,8 @@ public:
```go
func countSubarrays(nums []int, k int64) (ans int64) {
s, j := 0, 0
for i, v := range nums {
s += v
for i, x := range nums {
s += x
for int64(s*(i-j+1)) >= k {
s -= nums[j]
j++
Expand All @@ -270,6 +326,45 @@ func countSubarrays(nums []int, k int64) (ans int64) {
}
```

#### TypeScript

```ts
function countSubarrays(nums: number[], k: number): number {
let [ans, s, j] = [0, 0, 0];
for (let i = 0; i < nums.length; ++i) {
s += nums[i];
while (s * (i - j + 1) >= k) {
s -= nums[j++];
}
ans += i - j + 1;
}
return ans;
}
```

#### Rust

```rust
impl Solution {
pub fn count_subarrays(nums: Vec<i32>, k: i64) -> i64 {
let mut ans = 0i64;
let mut s = 0i64;
let mut j = 0;

for i in 0..nums.len() {
s += nums[i] as i64;
while s * (i as i64 - j as i64 + 1) >= k {
s -= nums[j] as i64;
j += 1;
}
ans += i as i64 - j as i64 + 1;
}

ans
}
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Loading