[杨小白]_leetcode_力扣_第 321 场周赛-第四题

184 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

前言

小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标1900分,现在1806!!

力扣第 321 场周赛-力扣

第 321 场周赛

周日打周赛的人都不多了,之前周赛都有6000来人打,可能现在秋招结束了吧,都快跌破5000了。

image.png

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.length
  • 1 <= n <= 105
  • 1 <= nums[i], k <= n
  • nums 中的整数互不相同

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结尾也是很欣慰了!

img.png