开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标1900分,现在1806!!
力扣第 321 场周赛-力扣
第 321 场周赛
周日打周赛的人都不多了,之前周赛都有6000来人打,可能现在秋招结束了吧,都快跌破5000了。
2488. 统计中位数为 K 的子数组
给你一个长度为 n 的数组 nums ,该数组由从 1 到 n 的 不同 整数组成。另给你一个正整数 k 。
统计并返回 num 中的 中位数 等于 k 的非空子数组的数目。
注意:
数组的中位数是按 递增 顺序排列后位于 中间 的那个元素,如果数组长度为偶数,则中位数是位于中间靠 左 的那个元素。
例如,[2,3,1,4] 的中位数是 2 ,[8,4,3,5,1] 的中位数是 4 。
子数组是数组中的一个连续部分。
示例1:
输入: nums = [3,2,1,4,5], k = 4
输出: 3
解释: 中位数等于 4 的子数组有:[4]、[4,5] 和 [1,4,5] 。
示例 2:
输入: nums = [2,3,1], k = 3
输出: 1
解释: [3] 是唯一一个中位数等于 3 的子数组。
提示
n == nums.length1 <= n <= 1051 <= nums[i], k <= nnums中的整数互不相同
2.代码
这个题不难简单说一下思路。
需要找到子数组的中位数为k,比k大的数有a个,比k小的数有b个
当子数组长度为偶数时,a - b = 1
当子数组长度为奇数时,a = b
所以,遍历数组,先找到等于k的数的下标为index
用前缀和思想,从index分别往前和往后遍历,如果大于k就+1,如果小于k就减一
例如nums = [3,2,1,4,5], k = 4
找到k后,往前往后遍历得到的新数组为 -2 -2 -1 0 1
那么就遍历左边的情况,找到a - b = 1 和b = a 的情况。
此时能包括左边的子数组的情况都考虑到了。
还有只包括右边不包括左边的,那就需要加入右边0的个数和1的个数即可。
class Solution {
public int countSubarrays(int[] nums, int k) {
int[] arr = new int[nums.length];
int index = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == k) {
index = i;
break;
}
}
int t = 0;
for (int i = index + 1; i < nums.length; i++) {
if (nums[i] > k) {
t++;
} else {
t--;
}
arr[i] = t;
}
t = 0;
for (int i = index - 1; i >= 0; i--) {
if (nums[i] > k) {
t++;
} else {
t--;
}
arr[i] = t;
}
HashMap<Integer, Integer> left = new HashMap<>();
for (int i = 0; i < index; i++) {
left.put(arr[i], left.getOrDefault(arr[i], 0) + 1);
}
HashMap<Integer, Integer> right = new HashMap<>();
for (int i = index + 1; i < arr.length; i++) {
right.put(arr[i], right.getOrDefault(arr[i], 0) + 1);
}
int res = 0;
for (Map.Entry<Integer, Integer> entry : right.entrySet()) {
int key = entry.getKey();
int value = entry.getValue();
if (key > 1) {
res = res + left.getOrDefault(-key, 0) * value;
res = res + left.getOrDefault(-key + 1, 0) * value;
}else if(key == 1) {
res = res + left.getOrDefault(-1, 0) * value;
res = res + left.getOrDefault(0, 0) * value;
res = res + value;
} else if (key == 0) {
res = res + left.getOrDefault(0, 0) * value;
res = res + left.getOrDefault(1, 0) * value;
res = res + value;
} else {
res = res + left.getOrDefault(-key, 0) * value;
res = res + left.getOrDefault(-key + 1, 0) * value;
}
}
res = res + left.getOrDefault(1,0);
res = res + left.getOrDefault(0,0);
return res + 1;
}
}
3.结束
这次力扣没想到周三早上就出分了,还挺快,已经knight了
11月以上knight结尾也是很欣慰了!