笔记用于个人复习和巩固,题解非原创,参考LeetCode官方题解以及各个大佬的解法,希望给大家带来帮助,同时笔记也能督促我学习进步

这周主要把滑动窗口和子串的题目刷了一遍

文章目录

  • Week2
    • D1 滑动窗口
      • 209. 长度最小的子数组
      • 713. 乘积小于 K 的子数组
      • 3. 无重复字符的最长子串
    • D2 定长滑窗&不定长滑窗
      • 定长滑窗
        • 定长滑窗套路
      • 不定长滑窗
    • D3
      • 560. 和为 K 的子数组
        • 暴力
        • 前缀和+哈希表
    • D4
      • 239. 滑动窗口最大值
        • 单调队列
    • D5
      • 76. 最小覆盖子串
    • D6
      • 53. 最大子数组和
        • 贪心
        • 动态规划
    • D7
      • 56. 合并区间

Week2

D1 滑动窗口

只有当数组中所有数都是非负数时,才能使用滑动窗口。

如果数组中包含负数不能使用标准的滑动窗口

滑动窗口的核心前提:

当窗口扩大时,和变大;窗口缩小时,和变小。

209. 长度最小的子数组

209. 长度最小的子数组

class Solution {public int minSubArrayLen(int target, int[] nums) {int n = nums.length;int ans = n + 1;int sum = 0;int left = 0;for(int right = 0;right < n;right++){sum += nums[right];while(sum >= target){ans = Math.min(ans,right - left + 1);sum -= nums[left];left++;}}return ans <= n ? ans : 0;}
}

713. 乘积小于 K 的子数组

713. 乘积小于 K 的子数组

class Solution {public int numSubarrayProductLessThanK(int[] nums, int k) {if(k <= 1){return 0;}int n = nums.length;int ans = 0;int prod = 1;int left = 0;for(int right = 0;right < n;right++){prod *= nums[right];while(prod >= k){ //不满足要求prod /= nums[left];left++; //缩小窗口}ans += right - left + 1;}return ans;}
}

3. 无重复字符的最长子串

3. 无重复字符的最长子串

class Solution {public int lengthOfLongestSubstring(String S) {char[] s = S.toCharArray();int ans = 0;int n = s.length;int left = 0;int[] cnt = new int[128];for(int right = 0;right < n;right++){char c = s[right];cnt[c]++;while(cnt[c] > 1){ //窗口有重复字符cnt[s[left]]--;//移除窗口左端点字符left++;//缩小窗口}ans = Math.max(ans,right - left + 1);}return ans;}
}

D2 定长滑窗&不定长滑窗

定长滑窗

class Solution {public List<Integer> findAnagrams(String s, String p) {List<Integer> ans = new ArrayList<>();int n = s.length(); //测量String的长度用.length()int[] cntP = new int[26]; //统计p的每种字母的出现次数int[] cntS = new int[26]; //统计s的长为p.length()的子串s'的每种字母的出现次数for(char c:p.toCharArray()){cntP[c - 'a']++;}for(int right = 0;right < n;right++){cntS[s.charAt(right) - 'a']++;int left = right - p.length() + 1;if(left < 0){continue; //窗口长度不够}if(Arrays.equals(cntS,cntP)){ans.add(left);}cntS[s.charAt(left) - 'a']--; //左端字母离开窗口}return ans;}
}

Arrays.equals(cntS, cntP) 是 Java 中用来 判断两个数组是否“完全相同” 的标准方法

✅ 它比较的是:

两个数组在以下方面是否完全一致:

比较项是否比较
1. 数组长度
2. 每个对应位置的元素值
3. 元素顺序是(顺序不同 → 不相等)

如果以上全部相同,返回 true;否则返回 false


定长滑窗套路

窗口右端点在 i 时,由于窗口长度为 k,所以窗口左端点为 ik+1。

三步:入-更新-出

  1. 入:下标为 i 的元素进入窗口,更新相关统计量。如果窗口左端点 i−k+1<0,则尚未形成第一个窗口,重复第一步。
  2. 更新:更新答案。一般是更新最大值/最小值。
  3. 出:下标为 i−k+1 的元素离开窗口,更新相关统计量,为下一个循环做准备。

不定长滑窗

class Solution {public List<Integer> findAnagrams(String s, String p) {List<Integer> ans = new ArrayList<>();int[] cnt = new int[26]; // 统计 p 的每种字母的出现次数for (char c : p.toCharArray()) {cnt[c - 'a']++; //s中出现就-- 若cnt<0则说明子串c太多 }int left = 0;for (int right = 0; right < s.length(); right++) {int c = s.charAt(right) - 'a';cnt[c]--; // 右端点字母进入窗口while (cnt[c] < 0) { // 字母 c 太多了cnt[s.charAt(left) - 'a']++; // 左端点字母离开窗口left++;}if (right - left + 1 == p.length()) { // s' 和 p 的每种字母的出现次数都相同ans.add(left); // s' 左端点下标加入答案}}return ans;}
}

代码实现时,可以把 cntS 和 cntP 合并成一个 cnt:

  • 对于 p 的字母 c,把 cnt[p] ++

  • 对于 s’ 的字母 c,把 cnt[c] –

  • 如果 cnt[c]<0,说明窗口中的字母 c 的个数比 p 的多,右移左端点。

D3

560. 和为 K 的子数组

560. 和为 K 的子数组

暴力

遍历得到所有子串并求和 筛选出符合条件的

class Solution {public int subarraySum(int[] nums, int k) {int ans = 0;int n = nums.length;for(int i = 0;i < n;i++){  //列举每个元素当子串结尾的情况int sum = 0;for(int j = i;j >= 0;j--){  //求所有以这个子串为结尾的和sum += nums[j];if(sum == k)ans++;}}return ans;}
}
前缀和+哈希表

前缀和pre[i]=pre[i−1]+nums[i]

[j…i] 这个子数组和为 k 这个条件我们可以转化为pre[i]−pre[j−1]==k

简单移项可得符合条件的下标 j 需要满足

pre[j−1]==pre[i]−k

class Solution {public int subarraySum(int[] nums, int k) {int ans = 0,pre = 0;int n = nums.length;HashMap<Integer,Integer>mp = new HashMap<>();mp.put(0,1);for(int i = 0;i < n;i++){pre += nums[i];if(mp.containsKey(pre - k)){ans += mp.get(pre - k);}mp.put(pre,mp.getOrDefault(pre,0) + 1);}return ans;}
}

D4

239. 滑动窗口最大值

239. 滑动窗口最大值

单调队列

单调队列套路

  1. 右边入(元素进入队尾,同时维护队列单调性
  2. 左边出(元素离开队首
  3. 记录/维护答案(根据队首
class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;int[] ans = new int[n - k + 1]; // 窗口个数Deque<Integer> q = new ArrayDeque<>(); // 更快的写法见【Java 数组】for (int i = 0; i < n; i++) {// 1. 右边入while (!q.isEmpty() && nums[q.getLast()] <= nums[i]) {q.removeLast(); // 维护 q 的单调性}q.addLast(i); // 注意保存的是下标,这样下面可以判断队首是否离开窗口// 2. 左边出int left = i - k + 1; // 窗口左端点if (q.getFirst() < left) { // 队首离开窗口q.removeFirst();}// 3. 在窗口左端点处记录答案if (left >= 0) {// 由于队首到队尾单调递减,所以窗口最大值就在队首ans[left] = nums[q.getFirst()];}}return ans;}
}

D5

76. 最小覆盖子串

76. 最小覆盖子串

class Solution {public String minWindow(String S, String t) {int[] cntS = new int[128]; // s 子串字母的出现次数int[] cntT = new int[128]; // t 中字母的出现次数for (char c : t.toCharArray()) {cntT[c]++;}char[] s = S.toCharArray();int m = s.length;int ansLeft = -1;int ansRight = m;int left = 0;for (int right = 0; right < m; right++) { // 移动子串右端点cntS[s[right]]++; // 右端点字母移入子串 如果 s[right] 是一个 char 类型的字符,它会被自动转换成对应的 ASCII/Unicode 数值(int),然后作为数组下标使用while (isCovered(cntS, cntT)) { // 涵盖if (right - left < ansRight - ansLeft) { // 找到更短的子串ansLeft = left; // 记录此时的左右端点ansRight = right;}cntS[s[left]]--; // 左端点字母移出子串left++;}}return ansLeft < 0 ? "" : S.substring(ansLeft, ansRight + 1);}private boolean isCovered(int[] cntS, int[] cntT) {for (int i = 'A'; i <= 'Z'; i++) {if (cntS[i] < cntT[i]) {return false;}}for (int i = 'a'; i <= 'z'; i++) {if (cntS[i] < cntT[i]) {return false;}}return true;}
}

D6

53. 最大子数组和

53. 最大子数组和

贪心

若指针所指当前元素之前的和小于0,则丢弃当前元素之前的数列

class Solution {public int maxSubArray(int[] nums) {int pre = 0, ans = nums[0];for (int x : nums) {if(pre < 0){pre = x;}else{pre += x;}ans = Math.max(pre,ans);}return ans;}
}
动态规划

考虑 nums[i] 单独成为一段还是加入 f(i−1) 对应的那一段,这取决于 nums[i] 和f(i−1)+nums[i] 的大小

class Solution {public int maxSubArray(int[] nums) {int pre = 0, maxAns = nums[0];for (int x : nums) {pre = Math.max(pre + x, x);maxAns = Math.max(maxAns, pre);}return maxAns;}
}

D7

56. 合并区间

56. 合并区间

一开始想到三种区间关系,覆盖,重叠,相离,不知道怎么把合并的区间添加到ans中

其实不用分出三种区间关系,直接判断能否合并就行,即前一个的right和后一个left的关系:

  • q_left <= p_right 可以合并
  • q_left > p_right 不可以合并

对于最后将合并好的区间添加的ans里也可以简单化:

  • 可合并:添加前一个区间p进ans 修改p_right为q_right(如果q_right更大的话)
  • 不可合并:直接将该区间加入
    在这里插入图片描述
class Solution {public int[][] merge(int[][] intervals) {Arrays.sort(intervals, (p, q) -> p[0] - q[0]); // 按照左端点从小到大排序List<int[]> ans = new ArrayList<>(); //不知道最后结果大小 没法用二维数组for (int[] p : intervals) {int m = ans.size();if (m > 0 && p[0] <= ans.get(m - 1)[1]) { // 可以合并ans.get(m - 1)[1] = Math.max(ans.get(m - 1)[1], p[1]); // 更新右端点最大值} else { // 不相交,无法合并ans.add(p);}}return ans.toArray(new int[ans.size()][]);}
}

return ans.toArray(new int[ans.size()][]);

作用是:List<int[]> 转换为 int[][](二维数组)并返回

为什么要写这一行?

  • 函数的返回类型是 int[][](二维数组)
  • 但我们使用 List<int[]> 来动态存储合并后的区间(因为 List 可以随时 add,而数组大小固定)

所以,在最后必须把 List 转成 int[][] 才能返回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/98070.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/98070.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/98070.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue2纯前端对接海康威视摄像头实现实时视频预览

vue2纯前端对接海康威视摄像头实现实时视频预览一、环境准备二、代码集成1.1 准备webrtcstreamer.js&#xff0c;粘贴即用&#xff0c;不用做任何修改1.2 封装视频组件&#xff0c;在需要视频的地方引入此封装的视频组件即可&#xff0c;也是粘贴即用&#xff0c;注意其中impor…

Android 设置禁止截图和禁止长截图

1.禁止截图 在 Activity 代码中 , 可以在调用 setContentView 函数之前 ,为 Window 窗口对象 设置 LayoutParams.FLAG_SECURE 标志位 , 可以禁止对本界面进行截屏 ,Window 窗口对象 , 可通过 getWindow 方法获取 ,核心代码如下 :getWindow().setFlags(LayoutParams.FLAG_SECUR…

AR 巡检在工业的应用|阿法龙XR云平台

AR 巡检的应用覆盖电力、石油化工、智能制造、轨道交通、冶金等对设备可靠性和安全性要求极高的行业&#xff0c;具体场景包括&#xff1a;电力行业变电站内设备的状态检查&#xff1a;通过 AR 眼镜扫描设备&#xff0c;实时显示设备额定参数、历史故障记录、实时传感器数据&am…

【C++】STL详解(七)—stack和queue的介绍及使用

✨ 坚持用 清晰易懂的图解 代码语言&#xff0c; 让每个知识点都 简单直观 &#xff01; &#x1f680; 个人主页 &#xff1a;不呆头 CSDN &#x1f331; 代码仓库 &#xff1a;不呆头 Gitee &#x1f4cc; 专栏系列 &#xff1a; &#x1f4d6; 《C语言》&#x1f9e9; 《…

深度学习周报(9.8~9.14)

目录 摘要 Abstract 1 LSTM相关网络总结与对比 1.1 理论总结 1.2 代码运行对比 2 量子计算入门 3 总结 摘要 本周首先总结了LSTM、Bi-LSTM与GRU的区别与优缺点&#xff0c;对比了三者实战的代码与效果&#xff0c;还另外拓展了一些循环神经网络变体&#xff08;包括窥视…

Quat 四元数库使用教程:应用场景概述

基础概念 四元数是一个包含四个元素的数组 [x, y, z, w]&#xff0c;其中 x,y,z表示虚部&#xff0c;w 表示实部。单位四元数常用于表示3D空间中的旋转。 1. 创建和初始化函数 create() - 创建单位四元数 应用场景&#xff1a;初始化一个新的四元数对象&#xff0c;通常作为其他…

【Java后端】Spring Boot 多模块项目实战:从零搭建父工程与子模块

如何用 Spring Boot 搭建一个父工程 (Parent Project)&#xff0c;并在其中包含多个子模块 (Module)&#xff0c;适合企业级项目或者需要分模块管理的场景。Spring Boot 多模块项目实战&#xff1a;从零搭建父工程与子模块在日常开发中&#xff0c;我们经常会遇到这样的需求&am…

企业级AI会议系统技术实现:快鹭如何用AI重构会议全流程

摘要 本文深度解析快鹭AI会议系统的核心技术架构&#xff0c;重点探讨其在语音识别、自然语言处理、数据集成和安全防护等方面的技术实现。通过对比传统会议系统的技术痛点&#xff0c;分析快鹭AI如何通过技术创新实现会议筹备时间减少67%、数据调取速度提升100倍的显著效果。…

【CSS学习笔记3】css特性

1css三大特性 1.1层叠性&#xff1a;就近原则&#xff0c;最新定义的样式 1.2继承性&#xff1a;子标签集成父标签的样式&#xff0c;如文本和字号 行高的继承&#xff1a;不加单位指的是当前文字大小的倍数 body {font: 12px/1.5 Microsoft YaHei;color: #be1313;} div {…

[C语言]常见排序算法①

1.排序的概念及常见的排序算法排序在咱们日常生活中十分的常见&#xff0c;就好比是网上购物的时候通常能够选择按照什么排序&#xff0c;比如价格、评论数量、销量等。那么接下来咱们就来了解一些关于排序的概念。排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xf…

文献阅读笔记:RS电子战测试与测量技术文档

信息来源&#xff1a;罗德与施瓦茨&#xff08;Rohde & Schwarz&#xff09;公司关于电子战&#xff08;Electronic Warfare, EW&#xff09;测试与测量解决方案专业技术文档。 该文档由台湾地区应用工程师Mike Wu撰写&#xff0c;核心围绕电子战基础、雷达系统、实战应用及…

别再纠结 Postman 和 Apifox 了!这款开源神器让 API 测试更简单

别再纠结 Postman 和 Apifox 了&#xff01;这款开源神器让 API 测试更简单&#x1f525; 作为一名开发者&#xff0c;你是否还在为选择 API 测试工具而纠结&#xff1f;Postman 太重、Apifox 要联网、付费功能限制多&#xff1f;今天给大家推荐一款完全免费的开源替代方案 ——…

微调神器LLaMA-Factory官方保姆级教程来了,从环境搭建到模型训练评估全覆盖

1. 项目背景 开源大模型如LLaMA&#xff0c;Qwen&#xff0c;Baichuan等主要都是使用通用数据进行训练而来&#xff0c;其对于不同下游的使用场景和垂直领域的效果有待进一步提升&#xff0c;衍生出了微调训练相关的需求&#xff0c;包含预训练&#xff08;pt&#xff09;&…

创建其他服务器账号

✅ 在 /home74 下创建新用户的完整步骤1. 创建用户并指定 home 目录和 shellsudo useradd -m -d /home74/USERNAME -s /bin/bash USERNAME-m&#xff1a;自动创建目录并复制 /etc/skel 默认配置文件&#xff08;.bashrc 等&#xff09;。-d&#xff1a;指定用户 home 路径&…

【WebGIS】Vue3使用 VueLeaflet + 天地图 搭建地图可视化平台(基础用法)

初始化 创建项目 nodejs 18.0.6npm 9.5.1 引入地图服务 VueLeaflet GitHub - vue-leaflet/vue-leaflet&#xff1a; vue-leaflet 与 vue3 兼容 Vue Leaflet (vue2-leaflet) package.josn安装版本 直接添加四个依赖 {// ..."scripts": {// ...},"depen…

OpenCV 开发 -- 图像阈值处理

文章目录[toc]1 基本概念2 简单阈值处理cv2.threshold3 自适应阈值处理cv2.adaptiveThreshold更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;OpenCV开发 &#x1f448;1 基本概念 图像阈值处理&#xff08;Thresholding&#xff09;是图像处理中的一种基本技术…

单串口服务器-工业级串口联网解决方案

在工业自动化、智能电网、环境监测等领域&#xff0c;传统串口设备&#xff08;如PLC、传感器、仪表等&#xff09;的网络化升级需求日益增长。博为智能单串口服务器凭借高性能硬件架构、多协议支持和工业级可靠性&#xff0c;为RS485设备提供稳定、高效的TCP/IP网络接入能力&a…

第 9 篇:深入浅出学 Java 语言(JDK8 版)—— 吃透泛型机制,筑牢 Java 类型安全防线

简介&#xff1a;聚焦 Java 泛型这一“类型安全保障”核心技术&#xff0c;从泛型解决的核心痛点&#xff08;非泛型代码的运行时类型错误、强制类型转换冗余&#xff09;切入&#xff0c;详解泛型的本质&#xff08;参数化类型&#xff09;、核心用法&#xff08;泛型类/接口/…

MySQL和Redis的数据一致性问题与业界常见解法

一、为什么会出现数据不一致&#xff1f; 根本原因在于&#xff1a;这是一个涉及两个独立存储系统的数据更新操作&#xff0c;它无法被包装成一个原子操作&#xff08;分布式事务&#xff09;。更新数据库和更新缓存是两个独立的步骤&#xff0c;无论在代码中如何排列这两个步骤…

coolshell文章阅读摘抄

coolshell文章阅读摘抄打好基础学好英语限制你的不是其它人&#xff0c;也不是环境&#xff0c;而是自己Java打好基础 程序语言&#xff1a;语言的原理&#xff0c;类库的实现&#xff0c;编程技术&#xff08;并发、异步等&#xff09;&#xff0c;编程范式&#xff0c;设计模…