刷题笔记 - 滑动窗口

文章目录

    • 滑动窗口
      • 最长无重复子串
      • 最小覆盖子串
      • 串联所有单词的子串
      • 长度最小的子数组
      • 滑动窗口最大值
      • 字符串的排列
      • 最小区间

滑动窗口

所有题目来自leetcode的回答:https://leetcode.cn/problems/longest-substring-without-repeating-characters/solutions/3982/hua-dong-chuang-kou-by-powcai

会员题没有列出来。

最长无重复子串

题目:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        if (n == 0) return 0;
        Map<Character, Integer> map = new HashMap<>();
        int res = 0, left = 0;
        for (int i = 0; i < n; i ++) {
            if (map.containsKey(s.charAt(i))) {
                left = Math.max(left, map.get(s.charAt(i)) + 1);
            }
            map.put(s.charAt(i), i);
            res = Math.max(res, i - left  + 1);
        }
        return res;
    }
}

最小覆盖子串

题目:https://leetcode.cn/problems/minimum-window-substring/description/

class Solution {

    Map<Character, Integer> cnts = new HashMap<>();
    Map<Character, Integer> cntt = new HashMap<>();

    public String minWindow(String s, String t) {
        int ls = s.length(), lt = t.length();
        int milen = Integer.MAX_VALUE, st = 0,  ed = 0, mist = 0, mied = 0;
        boolean isNull = false;
        for (int i = 0 ; i < lt; i ++) {
            cntt.put(t.charAt(i), cntt.getOrDefault(t.charAt(i), 0) + 1);
        }
        while (ed < ls) {
            if (cntt.containsKey(s.charAt(ed))) {
                cnts.put(s.charAt(ed), cnts.getOrDefault(s.charAt(ed), 0) + 1);
                while (check()) {  // 这里是while,一步更新到第二个在cntt里的字符,过滤掉无用字符
                    isNull = true;
                    if (milen > ed - st + 1) {
                        milen = ed - st + 1;
                        mist = st;
                        mied = ed;
                    }
                    if (cntt.containsKey(s.charAt(st))) {
                        cnts.put(s.charAt(st), cnts.getOrDefault(s.charAt(st), 0) - 1);
                    }
                    st ++;
                }
            }
            ed ++;
        }
        if (!isNull) return "";
        return s.substring(mist, mied + 1);
    }

    private boolean check() {
        Iterator iter = cntt.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            Character key = (Character) entry.getKey();
            Integer val = (Integer) entry.getValue();
            if (cnts.getOrDefault(key, 0) < val) return false;
        }
        return true;
    }
}

串联所有单词的子串

题目:https://leetcode.cn/problems/substring-with-concatenation-of-all-words/description/

题解:https://leetcode.cn/problems/substring-with-concatenation-of-all-words/solutions/3825/chuan-lian-suo-you-dan-ci-de-zi-chuan-by-powcai

// 对words中的所有单词,维护一个单词计数map
// 串联子串中保证了每个子单词的原字符顺序不变
class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        int ls = s.length(), n = words.length;
        int lw = n * words[0].length(), oneLen = words[0].length();
        List<Integer> res = new ArrayList<>();
        if (lw > ls) return res;
        Map<String, Integer> wordsMap = new HashMap<>();
        for (int i = 0; i < n; i ++) {
            wordsMap.put(words[i], wordsMap.getOrDefault(words[i], 0) + 1);
        }
        for (int i = 0; i < ls - lw + 1; i ++) {  //  i < ls - lw + 1,保证能枚举到最后一个窗口的第一个下标位置
            Map<String, Integer> tmpMap = new HashMap<>();
            for (int j = i; j < i + lw; j += oneLen) {
                String subStr = s.substring(j, j + oneLen);
                tmpMap.put(subStr, tmpMap.getOrDefault(subStr, 0) + 1);
            }
            if (wordsMap.equals(tmpMap)) res.add(i);
        }
        return res; 
    }
}

优化:(常规的滑动窗口思路,和最小覆盖子串的代码逻辑相似)

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        int ls = s.length(), n = words.length;
        int lw = n * words[0].length(), oneLen = words[0].length();
        List<Integer> res = new ArrayList<>();
        if (lw > ls) return res;
        Map<String, Integer> wordsMap = new HashMap<>();
        for (int i = 0; i < n; i ++) {
            wordsMap.put(words[i], wordsMap.getOrDefault(words[i], 0) + 1);
        }
        for (int i = 0; i < oneLen; i ++) {  // 保证枚举到所有单词[0...oneLen], [1...oneLen + 1], ...
            int st = i, ed = i, cnt = 0;
            Map<String, Integer> tmpMap = new HashMap<>();
            while (ed < ls - oneLen + 1) {  // 同解法一的判断
                String subStr = s.substring(ed, ed + oneLen);
                tmpMap.put(subStr, tmpMap.getOrDefault(subStr, 0) + 1);
                ed += oneLen;
                cnt ++;  // 当前窗口里有几个单词
                while(tmpMap.getOrDefault(subStr, 0) > wordsMap.getOrDefault(subStr, 0)) {
                    // 窗口里的单词并不在wordsMap里,移动窗口
                    // 或者,窗口里当前单词重复出现了,移动窗口
                    String stStr = s.substring(st, st + oneLen);  // 窗口里最左边的单词
                    tmpMap.put(stStr, tmpMap.getOrDefault(stStr, 0) - 1);
                    st += oneLen;
                    cnt --;
                }
                if (cnt == n) res.add(st);
            }
        }
        return res;
    }
}

再优化(直接跳过不在words里的单词和窗口):

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        int ls = s.length(), n = words.length;
        int lw = n * words[0].length(), oneLen = words[0].length();
        List<Integer> res = new ArrayList<>();
        if (lw > ls) return res;
        Map<String, Integer> wordsMap = new HashMap<>();
        for (int i = 0; i < n; i ++) {
            wordsMap.put(words[i], wordsMap.getOrDefault(words[i], 0) + 1);
        }
        for (int i = 0; i < oneLen; i ++) {  // 保证枚举到所有单词[0...oneLen], [1...oneLen + 1], ...
            int st = i, ed = i, cnt = 0;
            Map<String, Integer> tmpMap = new HashMap<>();
            while (ed < ls - oneLen + 1) {  // 同解法一的判断
                String subStr = s.substring(ed, ed + oneLen);
                ed += oneLen;
                if (!wordsMap.containsKey(subStr)) {
                    /**
                        当前窗口的当前单词不是words里的单词,肯定不符合题意,更新窗口。
                        题中要求所有串联单词必须挨在一起,这个判断过滤掉不挨在一起的窗口
                     */
                    cnt = 0;
                    st = ed;
                    tmpMap.clear();
                    continue;
                }
                tmpMap.put(subStr, tmpMap.getOrDefault(subStr, 0) + 1);
                cnt ++;  // 当前窗口里有几个单词
                while(tmpMap.getOrDefault(subStr, 0) > wordsMap.getOrDefault(subStr, 0)) {
                    // 窗口里的单词并不在wordsMap里,移动窗口
                    // 或者,窗口里当前单词重复出现了,移动窗口
                    String stStr = s.substring(st, st + oneLen);  // 窗口里最左边的单词
                    tmpMap.put(stStr, tmpMap.getOrDefault(stStr, 0) - 1);
                    st += oneLen;
                    cnt --;
                }
                if (cnt == n) res.add(st);
            }
        }
        return res;
    }
}

长度最小的子数组

题目:https://leetcode.cn/problems/minimum-size-subarray-sum/description/

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int milen = Integer.MAX_VALUE, st = 0, ed = 0, sum = 0;
        boolean isNull = false;
        while (ed < n) {
            sum += nums[ed];
            while (sum >= target) {
                isNull = true;
                if (milen > ed - st + 1) {
                    milen = ed - st + 1;
                }
                sum -= nums[st];
                st ++;
            }
            ed ++;
        }
        if (!isNull) return 0;
        return milen;
    }
}

滑动窗口最大值

题目:https://leetcode.cn/problems/sliding-window-maximum/description/

题解:https://leetcode.cn/problems/sliding-window-maximum/solutions/2361228/239-hua-dong-chuang-kou-zui-da-zhi-dan-d-u6h0

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        // 借鉴最小栈的思路,再O(1)时间内找出窗口内的最大值
        // 双向队列维持一个窗口内的非严格递减排序
        // 队头是窗口内的最大值
        int n = nums.length;
        if (k == 1) return nums;
        int[] res = new int[n - k + 1];
        Deque<Integer> dq = new LinkedList<>();
        int idx = 0;
        for (int i = 0; i < k; i ++) {
            while (!dq.isEmpty() && dq.peekLast() < nums[i]) {
                dq.removeLast();
            }
            dq.addLast(nums[i]);
        }
        res[idx ++] = dq.peekFirst();
        for (int i = k; i < n; i ++) {
            if (dq.peekFirst() == nums[i - k]) dq.removeFirst();
            while (!dq.isEmpty() && dq.peekLast() < nums[i]) {
                dq.removeLast();
            }
            dq.addLast(nums[i]);
            res[idx ++] = dq.peekFirst();
        }
        return res;
    }
}

字符串的排列

题目:https://leetcode.cn/problems/permutation-in-string/description/

题解-方法二:https://leetcode.cn/problems/smallest-range-covering-elements-from-k-lists/solutions/355881/zui-xiao-qu-jian-by-leetcode-solution

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int ls1 = s1.length(), ls2 = s2.length();
        if (ls1 > ls2) return false;
        int[] cnt1 = new int[26], cnt2 = new int[26];
        for (int i = 0; i < ls1; i ++) {
            cnt1[s1.charAt(i) - 'a'] ++;
            cnt2[s2.charAt(i) - 'a'] ++;
        }
        if (Arrays.equals(cnt1, cnt2)) return true;
        for (int i = ls1; i < ls2; i ++) {
            cnt2[s2.charAt(i - ls1) - 'a'] --;
            cnt2[s2.charAt(i) - 'a'] ++;
            if (Arrays.equals(cnt1, cnt2)) return true;
        }
        return false;
    }
}

最小区间

题目:https://leetcode.cn/problems/smallest-range-covering-elements-from-k-lists/description/

class Solution {
    public int[] smallestRange(List<List<Integer>> nums) {
        int n = nums.size();
        Map<Integer, List<Integer>> index = new HashMap<>();
        int mi = Integer.MAX_VALUE, mx = Integer.MIN_VALUE;
        for (int i = 0; i < n; i ++) {
            for (int item : nums.get(i)) {
                List<Integer> tmp = index.getOrDefault(item, new ArrayList<Integer>());
                tmp.add(i);
                index.put(item, tmp);
                if (mi > item) mi = item;
                if (mx < item) mx = item;
            }
        }
        int st = mi, ed = mi - 1, ansSt = 0, ansEd = Integer.MAX_VALUE, cnt = 0;
        // System.out.println(mi + ", " + mx);
        int[] interval = new int[n];   // 记录滑动窗口覆盖了多少区间,下标标识某个区间
        while (ed < mx) {
            ed ++;
            if (index.containsKey(ed)) {
                for (int idx : index.get(ed)) {  // 枚举被覆盖的区间
                    interval[idx] ++;
                    if (interval[idx] == 1) {  // idx标识的区间第一次被覆盖时,标记该区间被覆盖
                        cnt ++;
                    }
                    while (cnt == n) {  // 当所有区间被覆盖,更新最小区间和窗口
                        if (ed - st < ansEd - ansSt) {
                            // System.out.println("*--*-*-");
                            ansSt = st;
                            ansEd = ed;
                        }
                        if (index.containsKey(st)) {  // 更新最小区间的左端点,看是否能覆盖全部区间
                            for (int leftIdx : index.get(st)) {
                                interval[leftIdx] --;
                                if (interval[leftIdx] == 0) {
                                    cnt --;
                                }
                            }
                        }
                        st ++;
                    }
                }
            }
        }
        return new int[] {ansSt, ansEd};
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式引脚工作模式

一.引脚工作模式的基本概念 引脚的工作模式通常包括输入模式、输出模式和双向模式&#xff1a; 输入模式&#xff1a;引脚设置为输入模式时&#xff0c;可以接收外部信号或触发器的信号。这种模式通常用于读取传感器数据、接收外部设备的信号等。 输出模式&#xff1a;引脚设…

链表的阶乘

int FactorialSum(List L) {int res 0; // 结果初始化struct Node* x L; // 从链表的头节点开始// 遍历链表中的每一个节点while (x ! NULL) {int data x->Data; // 当前节点的值int y 1; // 用于计算当前节点值的阶乘// 计算当前节点值的阶乘for (int j 1; j < dat…

ROS 2边学边练(44)-- 从头开始构建一个视觉机器人模型

前言 从此篇开始我们就开始接触URDF(Unified Robot Description Format&#xff0c;统一机器人描述格式)&#xff0c;并利用其语法格式搭建我们自己的机器人模型。 动动手 开始之前我们需要确认是否安装joint_state_publisher功能包&#xff0c;如果有安装过二进制版本的urdf_…

单位档案寄存该怎么处理才好

处理单位档案寄存的方式可以根据实际情况来确定&#xff0c;以下是一些常见的处理方式&#xff1a; 1. 数字化存档&#xff1a;将单位档案进行数字化处理&#xff0c;通过扫描或拍照将文件转化为电子格式。这样可以方便查找和管理&#xff0c;减少纸质文件的存储量&#xff0c;…

iOS ------ 内存五大分区

1&#xff0c;内存的概念&#xff1a; 虚拟内存&#xff08;Virtual Memory&#xff09;&#xff1a;虚拟内存是操作系统提供的一种机制&#xff0c;它使得应用程序能够访问超出物理内存限制的内存空间。虚拟内存将应用程序的内存地址空间分割成固定大小的页面&#xff08;Pag…

elementui+vue通过下拉框多选字段进行搜索模糊匹配

从字典中选择的值为["01","03"],在最开始的时候进行的处理是类似于表单提交的时候将json对象转换成了String类型 nature:["01","03"] this.queryParams.nature JSON.stringify(this.queryParams.nature); mapper层 <if test&quo…

PHP单独项目启动演示

文章目录 phpstudy得到文件打开phpStudy.exe运行项目 phpstudy 得到文件 一般我们会得到这么一个项目文件&#xff0c;如果外层有“中文路径”&#xff0c;请剪切此内容作为项目根目录即可 打开phpStudy.exe 因为我又正常的编程环境和mysql&#xff0c;所以这里是正常的&a…

开机弹窗找不到OpenCL.dll是怎么回事,哪种修复方法更推荐

当用户在操作电脑过程中遇到系统提示“OpenCL.dll丢失”时&#xff0c;这究竟是怎么一回事呢&#xff1f;OpenCL.dll&#xff0c;作为Open Computing Language&#xff08;开放计算语言&#xff09;的重要动态链接库文件&#xff0c;它在图形处理器&#xff08;GPU&#xff09;…

企业内部适用的五大知识库工具测评推荐

随着企业规模的不断扩大和业务复杂性的增加&#xff0c;要想更高效地进行企业管理就不得不使用知识库管理工具。本文将对五款企业内部适用的知识库工具进行测评推荐&#xff0c;帮助企业选择出更适合自己的知识库管理工具。 一、Helplook AI知识库 Helplook AI知识库是一款搭建…

PotPlayer v1.7.22218 全格式影音播放器,无广绿色版!

软件介绍 PotPlayer是一款多功能且免费的媒体播放软件&#xff0c;兼容多种音频和视频格式。提供了丰富的功能性以及个性化设置&#xff0c;以迎合不同用户的需求。友好的用户界面&#xff0c;允许用户自定义皮肤和快捷键&#xff0c;提升了操作的便利性。 此外&#xff0c;Po…

JavaScript快速入门系列-1(JavaScript简介)

第一章:JavaScript简介 1. JavaScript简介1.1 什么是JavaScript1.2 JavaScript的历史与应用1.3 环境搭建:浏览器与Node.js2. JavaScript语言基础2.1 变量声明:let, const, var2.2 数据类型:字符串、数字、布尔值、对象、数组、null与undefined2.3 运算符:算术、比较、逻辑…

微信云小程序快速上手云数据库+云函数+云存储的操作

&#x1f680; 作者 &#xff1a;“二当家-小D” &#x1f680; 博主简介&#xff1a;⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人&#xff0c;8年开发架构经验&#xff0c;精通java,擅长分布式高并发架构,自动化压力测试&#xff0c;微服务容器化k…

探索Java的未来

探索 Java 的未来是一个非常有趣的话题。Java 是一种广泛使用的编程语言&#xff0c;自 1995 年诞生以来&#xff0c;它已经在软件开发领域占据了重要的地位。尽管有些人担心 Java 可能会因为新技术的出现而变得不再相关&#xff0c;但实际情况并非如此。让我们来看看一些关于 …

Python | Leetcode Python题解之第69题x的平方根

题目&#xff1a; 题解&#xff1a; class Solution:def mySqrt(self, x: int) -> int:if x 0:return 0C, x0 float(x), float(x)while True:xi 0.5 * (x0 C / x0)if abs(x0 - xi) < 1e-7:breakx0 xireturn int(x0)

AI Agent智能应用从0到1定制开发(wanjie)

AI Agent&#xff08;人工智能体&#xff09;是一种能够感知环境、进行决策和执行动作的智能实体。不同于传统的人工智能&#xff0c;AI Agent 具备通过独立思考、调用工具去逐步完成给定目标的能力。 「完结12章」AI Agent智能应用从0到1定制开发 AI Agent 和大模型的区别在…

Windows 虚机扩容C盘

Windows 虚机扩容C盘 操作思路1、新增磁盘容量2、划分磁盘空间3、扩容对应盘 操作步骤 操作思路 1、新增磁盘容量 2、划分磁盘空间 3、扩容对应盘 操作步骤 1、虚机新增磁盘空间 先确认宿主机是否有足够空间&#xff0c;有足够空间后&#xff0c;编辑虚机&#xff0c;增加…

【3D目标检测】常见相关指标说明

一、mAP指标 mean Average Precision&#xff08;平均精度均值&#xff09;&#xff0c;它是目标检测和信息检索等任务中的重要性能指标。mAP 通过综合考虑精度和召回率来衡量模型的总体性能。 1.1 精度&#xff08;Precision&#xff09; 表示检索到的目标中实际为正确目标…

嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

随着物联网和智能设备的快速发展&#xff0c;嵌入式开发和鸿蒙系统成为了当前技术领域的热门话题。鸿蒙系统作为华为推出的全场景分布式操作系统&#xff0c;旨在连接各种智能设备&#xff0c;提供无缝的跨设备体验。而南向开发则是鸿蒙系统中的一个重要方向&#xff0c;主要涉…

长难句打卡5.6

For H&M to offer a $5.95 knit miniskirt in all its 2,300-plus stores around the world, it must rely on low-wage overseas labor, order in volumes that strain natural resources, and use massive amounts of harmful chemicals. 翻译:H&M若要在其全球总共2…

OpenCV|简单绘制一个矩形

OpenCV中的rectangle() 为绘制矩形命令&#xff0c;形式如下&#xff1a; # (img: cv2.typing.MatLike, pt1: cv2.typing.Point, pt2: cv2.typing.Point, color: cv2.typing.Scalar, thickness: int ..., lineType: int ..., shift: int ...)cv2.rectangle(img, pt1, pt2, …
最新文章