diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index 9276122..78e8827 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -2432,3 +2432,111 @@ func subarraysWithKDistinct(nums []int, k int) (ans int) { return } ``` + +## day33 2024-03-31 + +### 2444. Count Subarrays With Fixed Bounds + +You are given an integer array nums and two integers minK and maxK. + +A fixed-bound subarray of nums is a subarray that satisfies the following conditions: + +The minimum value in the subarray is equal to minK. +The maximum value in the subarray is equal to maxK. +Return the number of fixed-bound subarrays. + +A subarray is a contiguous part of an array. + +![0331tqDltORpk8jM](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0331tqDltORpk8jM.png) + +### 题解 + +本题先求出数组中包含上下界的所有可行子区域, 可行子区域指所有连续的符合上下界要求的最长区域. 将这些区域的头尾下标保存到一个二维数组中. 对于每个可行区域, 使用该区域包含的全部子数组的个数减去不满足上下界要求的子数组个数, 不满足上下界要求的子数组个数求解使用滑动窗口是比较容易的, 从头开始滑动, 窗口内只能包含上界或者下届或者都不包含. 若直接求解该区域中包含的满足上下界的子数组个数则比较困难. 用子数组总个数和不满足上下界要求的子数组个数做差即可得到想求的满足上下界的子数组个数. 对于每个子区域都执行这样的操作, 并将求得的满足条件的子数组个数加和即可得到最终的结果, 注意处理上下界都是同一个数的边界情况. + +### 代码 + +```go +func countSubarrays(nums []int, minK int, maxK int) int64 { + begin := 0 + borders := [][]int{} + mincurrent := -1 + maxcurrent := -1 + var result int64 + // 找到所有可行区间 + for index, value := range nums{ + border := []int{} + if value == minK { + mincurrent = 1 + } + if value == maxK { + maxcurrent = 1 + } + if value > maxK || value < minK || index == len(nums)-1{ + if maxcurrent == -1 || mincurrent == -1{ + mincurrent = -1 + maxcurrent = -1 + begin = index + 1 + }else{ + if value <= maxK && value >= minK && index == len(nums) - 1 { + index += 1 + } + border = append(border, begin) + border = append(border, index) + borders = append(borders, border) + border = border[:0] + mincurrent = -1 + maxcurrent = -1 + begin = index + 1 + } + } + } + + // 求每个可行区间中解的数目并加和 求解可行区间已经保证区间内必有上下限存在 + for _, region := range borders{ + left := region[0] + right := region[1] + ismin := false + ismax := false + last := 0 + allarray := (right - left + 1) * (right - left) / 2 + left = 0 + outrange := 0 + for index, value := range nums[region[0]:right]{ + if value != minK && value != maxK{ + outrange += index - left + 1 + }else if value == minK{ + if value == maxK{ + left = index + 1 + continue + } + if ismax{ + left = last + 1 + ismax = false + ismin = true + }else if !ismin{ + ismin = true + } + last = index + outrange += index - left + 1 + }else{ + if ismin{ + left = last + 1 + ismin = false + ismax = true + }else if !ismax{ + ismax = true + } + last = index + outrange += index - left + 1 + } + } + result += int64(allarray - outrange) + } + return result +} + +``` + +### 总结 + +本次解题代码的运行速度超过了100%的提交, 因此不再看他人的题解了, 同时庆祝一下自己拿到了3月份的奖章, 证明这个月每天都在坚持. 下个月希望能继续坚持下去.