leecode2962 统计最大元素出现至少K次的子数组
这个题型属于滑动窗口的题型,由于需要统计元素出现的次数,所以我们需要额外的数据结构map
我的思路
-
我首先找出了数组最大值
-
之后我对这个数组进行遍历,直到找到
map.containsKey(max)&&map.get(max)>=k
此时我们对这个次数进行判断。-
我最开始的判断是直接写一个循环,从0开始,直到遍历出来的max元素大于已经添加到map集合的max元素个数减去k的时候停止,但这种方式有个问题就是时间复杂夫很高,只通过了622/634个,后续这个优化想了好久也没想到怎么优化的,就先放弃了。直接看题解了
public long countSubarrays(int[] nums, int k) {int max = 0;for (int x : nums) {max = Math.max(max, x);}int len = nums.length;int max=arr[len-1],count=0;Map<Integer,Integer> map = new HashMap<>();for(int right=0;right<len;right++){map.put(nums[right],map.getOrDefault(nums[right],0)+1);int left =0,count_temp=0;if(map.containsKey(max)&&map.get(max)>=k){while (count_temp<=map.get(max)-k){if(nums[left]==max){count_temp++;}left++;count++;}}}return count; }
-
优化思路,把这个循环计数,转化为计数一次。
for(int right=0;right<len;right++){map.put(nums[right],map.getOrDefault(nums[right],0)+1);while(map.containsKey(max)&&map.get(max)==k){if(nums[left]==max){map.put(max,map.get(max)-1);}left++;}count+=left; }
-
灵神的思路
太强了,我太死板了,以为这种统计次数还是需要用map集合来做,但实际上,不需要,只需要一个计数器就行了,
class Solution {public long countSubarrays(int[] nums, int k) {int mx = 0;for (int x : nums) {mx = Math.max(mx, x);}long ans = 0;int cntMx = 0, left = 0;for (int x : nums) {if (x == mx) {cntMx++;}while (cntMx == k) {if (nums[left] == mx) {cntMx--;}left++;}ans += left;}return ans;}
}作者:灵茶山艾府
链接:https://leetcode.cn/problems/count-subarrays-where-max-element-appears-at-least-k-times/solutions/2560940/hua-dong-chuang-kou-fu-ti-dan-pythonjava-xvwg/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。