leetcode update

This commit is contained in:
gameloader 2024-03-27 17:55:45 +08:00
parent 223aee627e
commit f27301812b

View File

@ -2114,3 +2114,75 @@ func abs(num int) int {
### 总结
查看最快速代码, 其将负数直接修改为整数类型最大值, 对于超过数组长度的数直接忽略, 不作处理, 其余的当作下标取对应位置的相反数. 这样处理起来思路比较清晰.
## day29 2024-03-27
### 13. Subarray Product Less Than K
Given an array of integers nums and an integer k, return the number of contiguous subarrays where the product of all the elements in the subarray is strictly less than k.
![0327Kf6RehBJGKTs](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0327Kf6RehBJGKTs.png)
### 题解
本题要求返回的是连续的相邻子数组, 第一个想到的就是滑动窗口, 设置窗口的前后指针, 当窗口内的积<k时, 扩大窗口, 并增加计数, 当窗口内的积k时, 缩小窗口, 直到重新满足<k的条件为止. 这里增加计数的地方需要仔细考量, 并不是扩大窗口且积<k时, 就将计数加一, 因为该题是求积, 所以当两个数的积<k时, 其实已经包含了每个数都小于k在其中, 同理, 当三个数积<k时, 包含了任意两个的组合积都<k, 而本题只要求连续相邻的子序列. 故每次窗口扩大且符合条件时增加的计数应该为当前窗口的长度. (可以自己考虑一下从2个数扩大到3个数时默认新增了几种符合要求的子序列, 应该是包含新增加的数本身, 加上相邻一个数, 加上相邻两个数三种情况, 前面两个数的情况在之前已经计数过了)
### 代码
```go
func numSubarrayProductLessThanK(nums []int, k int) int {
front := 0
back := 0
sum := 1
result := 0
for front < len(nums){
sum *= nums[front]
if sum < k{
front++
result += front - back
}else{
if front == back{
front++
back++
sum = 1
continue
}
sum /= nums[back]
sum /= nums[front]
back++
}
}
return result
}
```
### 总结
在查看速度更快的题解代码时, 发现可以通过内层循环一直缩小窗口到<k时, 才继续向下滑动窗口, 这样外层只需要不断向下遍历来扩大窗口即可. 这样写循环思路更清晰, 代码更简洁 如下
```go
func numSubarrayProductLessThanK(nums []int, k int) int {
if k <= 1 {
return 0
}
res := 0
p := 1
j := 0
for i := 0; i < len(nums); i++ {
p *= nums[i]
for p >= k {
p /= nums[j]
j++
}
res += i -j + 1
}
return res
}
```
想到这, 忽然明白, 其实核心在于只需要考虑以某个位置为结尾的向前连续符合要求的数组长度作为该位置处应该增加的计数数目即可. 这样就把整个问题拆分成了独立不关联的小问题. 将每个位置应该增加的计数数目累积, 就是最终的结果.