mirror of
https://gitlab.com/game-loader/hugo.git
synced 2025-04-20 05:52:07 +08:00
leetcode update
This commit is contained in:
parent
88805a6b58
commit
b475dbf3ed
@ -2342,3 +2342,93 @@ func countSubarrays(nums []int, k int) int64 {
|
|||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## day32 2024-03-30
|
||||||
|
|
||||||
|
### 992. Subarrays with K Different Integers
|
||||||
|
|
||||||
|
Given an integer array nums and an integer k, return the number of good subarrays of nums.
|
||||||
|
|
||||||
|
A good array is an array where the number of different integers in that array is exactly k.
|
||||||
|
|
||||||
|
For example, [1,2,3,1,2] has 3 different integers: 1, 2, and 3.
|
||||||
|
A subarray is a contiguous part of an array.
|
||||||
|

|
||||||
|
|
||||||
|
### 题解
|
||||||
|
|
||||||
|
本题仍然使用滑动窗口, 这几天连续做滑动窗口的题, 总结了滑动窗口的"三要素": 1. 什么时候扩大窗口 2. 双么时候缩小窗口 3. 缩小和扩大窗口时执行哪些操作
|
||||||
|
对于本题, 题目中要求计数正好包含k个不同数的子数组的个数, 求精确包含k个这种问题往往比较困难, 可以转化为求解包含≤k个和≤k-1个不同数的子数组个数的差. 这种思路求解起来非常方便. 对于求解包含≤k个不同数的子数组的个数, 当数组中包含不同数个数不足k时, 扩大窗口同时将计数增加当前窗口的长度, 若为k+1, 则缩小窗口至正好完全去除了一个数(若某个数只出现了1次, 去掉后窗口内不同数个数就是k, 若不止一次, 则去掉了不同数个数也没有变化, 故要继续向下遍历). 最后求≤k和≤k-1情况的计数值做差即可.
|
||||||
|
|
||||||
|
### 代码
|
||||||
|
|
||||||
|
```go
|
||||||
|
func subarraysWithKDistinct(nums []int, k int) int {
|
||||||
|
|
||||||
|
return countk(nums, k) - countk(nums, k-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func countk(nums []int, k int) int {
|
||||||
|
count := map[int]int{}
|
||||||
|
different := 0
|
||||||
|
left := 0
|
||||||
|
result := 0
|
||||||
|
for index, value := range nums {
|
||||||
|
_, exist := count[value]
|
||||||
|
if !exist {
|
||||||
|
different++
|
||||||
|
count[value] = 1
|
||||||
|
} else {
|
||||||
|
count[value]++
|
||||||
|
}
|
||||||
|
if different <= k {
|
||||||
|
result += index - left + 1
|
||||||
|
}
|
||||||
|
if different == k+1 {
|
||||||
|
for count[nums[left]] > 1 {
|
||||||
|
count[nums[left]]--
|
||||||
|
left++
|
||||||
|
}
|
||||||
|
delete(count, nums[left])
|
||||||
|
left++
|
||||||
|
different--
|
||||||
|
result += index - left + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
解题时没有注意题目限制, 后来查看最快解法发现忽略了题目中的数的范围, 题目中的数组中的数的大小不超过数组的长度, 数的范围已知, 因此可以使用数组代替哈希表来计数这样可以大大加快解题速度.
|
||||||
|
|
||||||
|
```go
|
||||||
|
func subarraysWithKDistinct(nums []int, k int) (ans int) {
|
||||||
|
f := func(k int) []int {
|
||||||
|
n := len(nums)
|
||||||
|
pos := make([]int, n)
|
||||||
|
cnt := make([]int, n+1)
|
||||||
|
s, j := 0, 0
|
||||||
|
for i, x := range nums {
|
||||||
|
cnt[x]++
|
||||||
|
if cnt[x] == 1 {
|
||||||
|
s++
|
||||||
|
}
|
||||||
|
for ; s > k; j++ {
|
||||||
|
cnt[nums[j]]--
|
||||||
|
if cnt[nums[j]] == 0 {
|
||||||
|
s--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos[i] = j
|
||||||
|
}
|
||||||
|
return pos
|
||||||
|
}
|
||||||
|
left, right := f(k), f(k-1)
|
||||||
|
for i := range left {
|
||||||
|
ans += right[i] - left[i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user