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
|
||||
}
|
||||
```
|
||||
|
||||
## 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