leetcode update

This commit is contained in:
gameloader 2024-03-30 11:27:20 +08:00
parent 88805a6b58
commit b475dbf3ed

View File

@ -2342,3 +2342,93 @@ func countSubarrays(nums []int, k int) int64 {
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.
![0330GvIAMJljJeoJ](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0330GvIAMJljJeoJ.png)
### 题解
本题仍然使用滑动窗口, 这几天连续做滑动窗口的题, 总结了滑动窗口的"三要素": 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
}
```