当前位置: 首页 > news >正文

Day2--滑动窗口与双指针--2090. 半径为 k 的子数组平均值,2379. 得到 K 个黑块的最少涂色次数,2841. 几乎唯一子数组的最大和

Day2–滑动窗口与双指针–2090. 半径为 k 的子数组平均值,2379. 得到 K 个黑块的最少涂色次数,2841. 几乎唯一子数组的最大和

今天要训练的题目类型是:【定长滑动窗口】,题单来自@灵艾山茶府。

2090. 半径为 k 的子数组平均值

思路【我】:

  1. 先让数组默认填充-1,这样不用自己填充
  2. 直接让k变成我们熟知的窗口大小,在填avg的时候,再求回窗口的中心
  3. 注意元素大小,sum要用long类型
  4. 定长滑动窗口三部曲:入–更新–出。
class Solution {public int[] getAverages(int[] nums, int k) {// 直接让k变成我们熟知的窗口大小k = 2 * k + 1;int n = nums.length;// 结果集先填充-1int[] avg = new int[n];Arrays.fill(avg, -1);// 剪枝:如果n小于窗口,返回if (n < k) {return avg;}// 踩坑:没注意元素大小,累计和已经超过int上限了,要longlong sum = 0;// 开始滑动窗口for (int i = 0; i < n; i++) {// 1,右指针(i)进窗sum += nums[i];// 没到窗口大小,跳过if (i < k - 1) {continue;}// 2,更新结果集。这里要用i-k/2,找回中心位置// 因为sum是long,所以要强行转为intavg[i - k / 2] = (int) (sum / k);// 3,左指针(i-k=1)退出窗口sum -= nums[i - k + 1];}return avg;}
}

思路:

写法二:用window变量

class Solution {public int[] getAverages(int[] nums, int k) {int n = nums.length;int window = 2 * k + 1;// 结果集先填充-1int[] avg = new int[n];Arrays.fill(avg, -1);// 剪枝:如果n小于窗口,返回if (n < window) {return avg;}long sum = 0;// 开始滑动窗口for (int i = 0; i < n; i++) {// 1,右指针(i)进窗sum += nums[i];// 没到窗口大小,跳过if (i < window - 1) {continue;}// 索引在窗口中心位置avg[i - k] = (int) (sum / window);// 3,左指针(i-window+1)退出窗口sum -= nums[i - window + 1];}return avg;}
}

2379. 得到 K 个黑块的最少涂色次数

思路【我】:

定长滑动窗口模板题。

定长滑动窗口三部曲:入–更新–出。

class Solution {public int minimumRecolors(String blocks, int k) {char[] ch = blocks.toCharArray();int n = ch.length;// 初始化int minCount = Integer.MAX_VALUE;int count = 0;// 开始滑动for (int i = 0; i < n; i++) {// 1,右指针(i)入窗if (ch[i] == 'W') {count++;}// 没到窗口大小,继续if (i < k - 1) {continue;}// 2,更新if (count < minCount) {minCount = count;}// 3,左指针(i-k+1)出窗if (ch[i - k + 1] == 'W') {count--;}}return minCount;}
}

2841. 几乎唯一子数组的最大和

思路【我】:

  1. 在传统滑动窗口的基础上,多添加一个mapmap<元素,出现次数>来统计窗口内元素的出现次数,map.size()就是不同种元素的个数。
  2. 注意返回值是long类型的
  3. 定长滑动窗口三部曲:入–更新–出。
    1. 入:右指针(i)入栈,map统计<元素,出现次数>
    2. 更新,要先满足不同种元素个数大于等于m
    3. 左指针出窗,map对应要减少该元素的出现次数,如果为0,要remove掉
class Solution {public long maxSum(List<Integer> nums, int m, int k) {// 先确定是几乎唯一子数组,再求最大和。int[] arr = nums.stream().mapToInt(Integer::intValue).toArray();int n = arr.length;// 使用map<元素,出现次数>来统计窗口内,元素的出现次数,map.size()就是不同种元素的个数Map<Integer, Integer> map = new HashMap<>();// 注意要返回的是long啊,又踩坑了long sum = 0;long maxSum = 0;// 开始滑动窗口for (int i = 0; i < n; i++) {// 右指针(i)入栈,map统计<元素,出现次数>sum += arr[i];map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);// 如果还不到窗口大小,继续if (i < k - 1) {continue;}// 2,更新,要先满足不同种元素个数大于等于mif (sum > maxSum && map.size() >= m) {maxSum = sum;}// 3,左指针出窗,map对应要减少该元素的出现次数,如果为0,要remove掉int out = arr[i - k + 1];sum -= out;if (map.get(out) == 1) {map.remove(out);} else {map.put(out, map.get(out) - 1);}}return maxSum;}
}

map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);可以写成map.merge(arr[i], 1, Integer::sum);

其中前者需要两次哈希操作,一次获取值,一次更新值。后者只需要一次哈希操作。

因此,merge 在理论上会略快一点,尤其是在哈希表较大或哈希冲突较多的场景下,减少一次哈希操作的优势会更明显。

http://www.xdnf.cn/news/1308583.html

相关文章:

  • Windows 基于ACL(访问控制列表)的权限管理
  • Manus AI与多语言手写识别的技术突破与行业变革
  • 数学建模Topsis法笔记
  • 【php反序列化介绍与常见触发方法】
  • Bash常用操作总结
  • 9.从零开始写LINUX内核——设置中断描述符表
  • RK3568 NPU RKNN(五):RKNN-ToolKit-lite2板端推理
  • linux I2C核心、总线与设备驱动
  • Dify实战应用指南(上传需求稿生成测试用例)
  • 守护品质安全,防伪溯源系统打造全链路信任体系
  • MySQL异步连接池的学习(五)
  • 海康机器人3D相机的应用
  • Docker目录的迁移
  • OpenCV Python——图像拼接(一)(图像拼接原理、基础知识、单应性矩阵 + 图像变换 + 拼接)
  • Python爬虫实战:研究Scrapy Spiders ,构建豆瓣网电影数据分析处理系统
  • CSV 生成 Gantt 甘特图
  • aws(学习笔记第五十一课) ECS集中练习(3)
  • 初识c语言————宏定义和调用
  • Trae中`settings.json`文件的Java配置项功能详解(一)
  • 云原生俱乐部-RH124知识点总结(1)
  • 安卓11 12系统修改定制化_____列举与安卓 9、10 系统在定制化方面的差异与权限不同
  • 【科普向-第一篇】数字钥匙生态全景:手机厂商、车厂与协议之争
  • Flutter Provider 模式实现:基于 InheritedWidget 的状态管理实现
  • 矩阵链相乘的最少乘法次数(动态规划解法)
  • 开源 Arkts 鸿蒙应用 开发(十七)通讯--http多文件下载
  • bilibili视频总结
  • RK3568 NPU RKNN(一):概念理清
  • 【P14 3-6 】OpenCV Python——视频加载、摄像头调用、视频基本信息获取(宽、高、帧率、总帧数)
  • 10-verilog的EEPROM驱动-单字节读写
  • 罗技MX Anywhere 2S鼠标修复记录