【剑指offer刷题记录 java版】数组双指针 之 滑动窗口

news2024/11/17 21:51:34

本系列文章记录labuladong的算法小抄中剑指offer题目


【剑指offer刷题记录 java版】数组双指针 之 滑动窗口

  • 剑指 Offer 48. 最长不含重复字符的子字符串
  • 剑指 Offer II 014. 字符串中的变位词
  • 剑指 Offer II 015. 字符串中的所有变位词
  • 剑指 Offer II 016. 不含重复字符的最长子字符串
  • 剑指 Offer II 017. 含有所有字符的最短字符串(难)
  • 剑指 Offer 30. 包含min函数的栈
  • 剑指 Offer 59 - I. 滑动窗口的最大值(难)
  • 总结


剑指 Offer 48. 最长不含重复字符的子字符串

题目链接:https://leetcode.cn/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/
在这里插入图片描述

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap();
        int left=0,right=0;
        int length=0;
        while(right<s.length()){
            char c = s.charAt(right);
            map.put(c,map.getOrDefault(c,0)+1);// 进行窗口内数据的一系列更新
            right++;
            while(map.get(c)>1){// 判断左侧窗口是否要收缩
                char temp = s.charAt(left);
                map.put(temp, map.get(temp)-1);
                left++;
            }
            length = Math.max(length,right-left);
        }
        return length;
    }
}

剑指 Offer II 014. 字符串中的变位词

题目链接:https://leetcode.cn/problems/MPnaiL/
在这里插入图片描述

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        //map记录s1中包含的字母及数量
        Map<Character,Integer> map = new HashMap<>();
        for(int i=0;i<s1.length();i++){
            map.put(s1.charAt(i),map.getOrDefault(s1.charAt(i),0)+1);
        }

        //map2记录s2中,曾出现在s1中的字母及数量
        Map<Character,Integer> map2 = new HashMap<>();
        int left=0, right=0;
        int valid=0;//valid记录数量相同的字母的个数
        while(right<s2.length()){
            char c = s2.charAt(right);
            if(map.containsKey(c)){
                map2.put(c,map2.getOrDefault(c,0)+1);
                if (map2.get(c).equals(map.get(c)))
                    valid++;
            }
            right++;

            while(right-left==s1.length()){
                // 在这里判断是否找到了合法的子串
                if (valid == map.size())
                    return true;
                char d = s2.charAt(left);
                // 进行窗口内数据的一系列更新
                if (map.containsKey(d)) {
                    if (map2.get(d).equals(map.get(d)))
                        valid--;
                    map2.put(d, map2.get(d) - 1);
                }
                left++;
            }
        }
        return false;
    }
}

//因为只有26个小写英文字母,可以使用数组记录
class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int n = s1.length(), m = s2.length();
        if (n > m) {
            return false;
        }
        int[] cnt = new int[26];
        for (int i = 0; i < n; ++i) {
            --cnt[s1.charAt(i) - 'a'];
            ++cnt[s2.charAt(i) - 'a'];
        }
        int diff = 0;
        for (int c : cnt) {
            if (c != 0) {
                ++diff;
            }
        }
        if (diff == 0) {
            return true;
        }
        for (int i = n; i < m; ++i) {
            int x = s2.charAt(i) - 'a', y = s2.charAt(i - n) - 'a';
            // 滑窗右边扩张左边收缩
            if (x == y) continue;
            if (cnt[x] == 0) {++diff;}
            ++cnt[x];
            if (cnt[y] == 0) {++diff;}
            --cnt[y];

            // 根据现状判断有几处不同
            if (cnt[x] == 0) {--diff;}
            if (cnt[y] == 0) {--diff;}
            if (diff == 0) {return true;}
        }
        return false;
    }
}

剑指 Offer II 015. 字符串中的所有变位词

题目链接:https://leetcode.cn/problems/VabMRr/
在这里插入图片描述

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int m=s.length(), n=p.length();
        if(m<n){
            return new ArrayList<Integer>();
        }

        List<Integer> res = new ArrayList<>();
        int[] count = new int[26];
        for(int i=0;i<p.length();i++){
            count[p.charAt(i)-'a']--;
            count[s.charAt(i)-'a']++;
        }

        int diff=0;
        for(int num: count){
            if(num!=0) diff++;
        }
        

        if(diff==0){
            res.add(0);
        }

        for(int i=n; i<m;i++){
            //窗口下标范围为 [i-n, i)
            int index1 = s.charAt(i)-'a';//右边元素
            int index2 = s.charAt(i-n)-'a';//左边元素
            
            if(count[index1]==0) diff++;
            count[index1]++;
            if(count[index1]==0) diff--;

            if(count[index2]==0) diff++;
            count[index2]--;
            if(count[index2]==0) diff--;

            if(diff==0){
                res.add(i-n+1);
            }
        }
        return res;
    }
}

剑指 Offer II 016. 不含重复字符的最长子字符串

题目链接:https://leetcode.cn/problems/wtcaE1/
在这里插入图片描述

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s=="")return 0;
        int left=0,right=0;
        int length=0;
        // 使用哈希表记录窗口内字符出现次数
        Map<Character, Integer> map = new HashMap<>();
        while(right<s.length()){
            char c = s.charAt(right);
            right++;
            map.put(c, map.getOrDefault(c,0)+1);

            //如果窗口中包含c
            while(map.get(c)>=2){
                char temp = s.charAt(left);
                map.put(temp, map.get(temp)-1);
                left++;
            }
            length=Math.max(length,right-left);
        }
        return length;
    }
}

剑指 Offer II 017. 含有所有字符的最短字符串(难)

题目链接:https://leetcode.cn/problems/M1oyTv/
截图
进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

class Solution {
    Map<Character, Integer> ori = new HashMap<Character, Integer>();
    Map<Character, Integer> cnt = new HashMap<Character, Integer>();

    public String minWindow(String s, String t) {
        int tLen = t.length();
        for (int i = 0; i < tLen; i++) {
            char c = t.charAt(i);
            ori.put(c, ori.getOrDefault(c, 0) + 1);
        }
        int l = 0, r = -1;
        int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
        int sLen = s.length();
        while (r < sLen) {
            ++r;
            if (r < sLen && ori.containsKey(s.charAt(r))) {
                cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
            }
            while (check() && l <= r) {
                if (r - l + 1 < len) {
                    len = r - l + 1;
                    ansL = l;
                    ansR = l + len;
                }
                if (ori.containsKey(s.charAt(l))) {
                    cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
                }
                ++l;
            }
        }
        return ansL == -1 ? "" : s.substring(ansL, ansR);
    }

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

剑指 Offer 30. 包含min函数的栈

题目链接:https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof/
在这里插入图片描述

class MinStack {
    Deque<Integer> dq;
    Deque<Integer> minDq;

    /** initialize your data structure here. */
    public MinStack() {
        dq = new LinkedList<>();
        minDq = new LinkedList();
        minDq.offerLast(Integer.MAX_VALUE);//注意为了防止空栈,要在栈底添加最大元素
    }
    
    public void push(int x) {
        dq.offerLast(x);
        minDq.offerLast(Math.min(x,minDq.peekLast()));
    }
    
    public void pop() {
        dq.pollLast();
        minDq.pollLast();
    }
    
    public int top() {
        return dq.peekLast();
    }
    
    public int min() {
        return minDq.peekLast();
    }
}

剑指 Offer 59 - I. 滑动窗口的最大值(难)

题目链接:https://leetcode.cn/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/
截图
单调队列

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        Deque<Integer> deque = new LinkedList<Integer>();
        for (int i = 0; i < k; ++i) {
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();
            }
            deque.offerLast(i);
        }

        int[] ans = new int[n - k + 1];
        ans[0] = nums[deque.peekFirst()];
        for (int i = k; i < n; ++i) {
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();
            }
            deque.offerLast(i);
            while (deque.peekFirst() <= i - k) {
                deque.pollFirst();
            }
            ans[i - k + 1] = nums[deque.peekFirst()];
        }
        return ans;
    }
}

总结

滑动窗口要先扩张后收缩,即先移动右边指针,再移动左边指针。
固定大小的窗口使用for循环遍历,窗口大小不固定时使用while遍历。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

应用程序监控

什么是应用程序监控 应用程序监控是一项基本功能&#xff0c;可以实时分析关键业务应用程序的前端和后端性能。应用程序监控通过提供有关应用程序可用性、性能和最终用户体验的宝贵见解&#xff0c;在确保应用程序不间断运行方面发挥着至关重要的作用。主动监控应用程序有助于…

Spark SQL数据源的基本操作

文章目录 一、基本操作二、默认数据源&#xff08;一&#xff09;默认数据源Parquet&#xff08;二&#xff09;案例演示读取Parquet文件1、在Spark Shell中演示练习1、将student.txt文件转换成student.parquet练习2、读取student.parquet文件得到学生数据帧&#xff0c;并显示…

MQ消息传递方式

发布订阅模式 发布订阅模式有点类似于我们日常生活中订阅报纸。每年到年尾的时候&#xff0c;邮局就会发一本报纸集合让我们来选择订阅哪一个。在这个表里头列了所有出版发行的报纸&#xff0c;那么对于我们每一个订阅者来说&#xff0c;我们可以选择一份或者多份报纸。比如北…

ESP32(MicroPython) 矩阵键盘电子琴+RGB灯

本程序相比上一个矩阵键盘电子琴程序增加了一个矩阵键盘&#xff0c;并把三个矩阵键盘的同一行相连&#xff0c;扫描周期缩短到40ms。增加RGB灯带&#xff0c;每个周期刷新一个灯&#xff08;随机颜色&#xff09;。 代码如下 #导入Pin模块 from machine import Pin import t…

Django rest framework基本知识

使用pycharm生成Django项目后&#xff0c;会生成工程目录和app目录 工程目录下5个文件&#xff0c;settings.py是全局配置相关的 urls.py是路有相关的 app相关的目录 models.py 数据库ORM对应的模型类 serializers.py 序列化与反序列化处理 views.py 根据request进行…

线性神经网络

线性神经网络 我们应该从线性神经网络开始&#xff0c;去逐步了解深度神经网络&#xff08;深度学习&#xff09;的各种复杂结构和底层原理。 1. 线性回归 用一个线性的模型来拟合数据与它们的标签之间的映射&#xff0c;用于回归问题。 1.1 构造线性模型&#xff1a; y ω…

Fiddler Orchestra用户指南:打造高效协同调试利器

引言&#xff1a;今天Fiddler更新到5.0版本后&#xff0c;小酋不经意间晃到了“Fiddler Orchestra”选项卡。爱折腾的小酋赶紧链接到官方用户指南一睹为快&#xff0c;看看这是什么东西&#xff0c;实现了什么新功能。下面是小酋看后做的一个翻译抢先版。 这是了解和设置Fiddl…

i5 3470+XSB75M-PK+HD 7750安装黑苹果macOS Big Sur 11.7.7

我本次使用的是 HD 7750 进行安装黑苹果&#xff08;闲鱼80元买的&#xff09;&#xff0c;这款显卡直接就是免驱&#xff0c;最高可以安装的版本是 macOS Monterey &#xff0c;但是建议安装至 macOS Big Sur 以获得较好的体验。 EFI&#xff08;OC引导&#xff09; EFI.zip …

RabbitMQ高阶使用队列实现

目录 1 从打车开始说起1.1 需要解决的问题1.1.1 打车排队 2 排队人数2.1 需求2.1.1 需求分析 2.2 实现方案2.2.1 MySQL2.2.1.1 入队2.2.1.2 获取进度2.2.1.3 遇到问题 2.2.3 Redis Zset 2.3 排队人数架构介绍2.4 数据结构2.4.2 zset结构2.4.1 雪花算法 2.5 功能实现2.5.1 派单2…

Java 实现反转一个链表

文章目录 思路核心四步骤循环移动代码实现 思路 翻转指的是改变链表中结点的指向&#xff0c;而不是将它的数据反转。 上图展示出的就是一个反转前的链表&#xff0c;下图展示一个反转后的链表。 根据上图可以看出&#xff0c;结点的地址和数据都没有改变&#xff0c;改变的…

Java SSM框架基础面试题

一、Spring面试题 1、Spring 在ssm中起什么作用&#xff1f; Spring&#xff1a;轻量级框架作用&#xff1a;Bean工厂&#xff0c;用来管理Bean的生命周期和框架集成。两大核心&#xff1a; 1、IOC/DI(控制反转/依赖注入) &#xff1a;把dao依赖注入到service层&#xff0c;s…

Java SSM框架面试题

sql 中 ${} 和 #{}的区别&#xff1a; #将传入的参数都当成一个字符串&#xff0c;会对自动传入的数据加一个双引号。如&#xff1a;order by #{age}&#xff0c;如果传入的值是18,那么解析成sql时的值为order by “18”, 如果传入 age ,则会解析为 order by “age”将传入的参…

6.S081——Lab4——trap lab

0.briefly speaking 这是MIT 6.S081 Fall 2021课程的第四个实验&#xff0c;它是有关陷阱机制的一系列小问题&#xff0c;如果对陷阱机制仍有疑问&#xff0c;可以参考我之前写的其他3篇博客&#xff0c;它们很好地解释了一些背景知识&#xff1a; 用户态陷阱(以系统调用为例…

oracle 19c 部署

安装前的基础环境和用户配置等参考rac部署篇oracle rac部署 一、资源准备 将数据库软件上传解压到oracle的家目录(注意解压后的用户属组) [oraclerac1 ~]$ unzip -d $ORACLE_HOME xxxx.zip 二、在xmanager或者vnc中执行安装 [oraclerac1 db_1]$ ./runInstaller 先安装一个数据…

SSM 框架常见面试题

1 Spring面试题 1、Spring 在ssm中起什么作用&#xff1f; Spring&#xff1a;轻量级框架 作用&#xff1a;Bean工厂&#xff0c;用来管理Bean的生命周期和框架集成。 两大核心&#xff1a;1、IOC/DI(控制反转/依赖注入) &#xff1a;把dao依赖注入到service层&#xff0c;ser…

5.3、Dockerfile内命令

【docker】CMD ENTRYPOINT 区别 终极解读&#xff01;_绝世好阿狸的博客-CSDN博客 0、上下文路径 $ docker build -t nginx:v3 . # . 是上下文路径&#xff0c;那么什么是上下文路径呢&#xff1f; 上下文路径&#xff1a;指docker在构建镜像时想使用本机的文件&#xff0c;…

缓冲区溢出与防护

目录 一、初识缓冲区溢出 1.1 缓冲区溢出概念 1.2 缓存区 1.3 缓存区溢出的危害 1.4 缓存区溢出事件 二、缓存区溢出攻击 2.1 溢出原理 2.2 典型的寄存器 三、缓存区溢出防御 3.1 缓冲区溢出攻击目标 3.2 缓冲区溢出条件 3.3 缓冲区溢出防范 3.3.1 程序设计过程中…

【后端开发】狂神笔记:Redis进阶

文章目录 1 Redis事务1.1 Redis事务简介1.2 Redis事务操作过程1.2.1 开启事务--->执行事务1.2.2 取消事务(discurd) 1.3 事务错误1.3.1 编译期异常1.3.2 运行时异常 2 Redis实现乐观锁2.1 乐观锁和悲观锁2.2 正常执行2.3 测试异常执行 3 Jedis3.1 导入依赖3.2 编码测试3.2.1…

青翼科技自研模块化互联产品 • 模拟采集FMC子卡【产品资料】

FMC122是一款基于FMC标准规范&#xff0c;实现2路16-bit、1GSPS ADC同步采集&#xff0c;2路16-bit 2.5GSPS DAC同步回放功能子卡模块。该模块遵循VITA57.1标准&#xff0c;可直接与FPGA载卡配合使用&#xff0c;板卡ADC器件采用TI的ADS54J60芯片&#xff0c;该芯片具有两个模拟…

EasyExcel实现execl导入导出

引言 在实际开发中&#xff0c;处理 Excel 文件是一个常见的需求。EasyExcel 是一个基于 Java 的开源库&#xff0c;提供了简单易用的 API&#xff0c;可以方便地读取和写入 Excel 文件。本文将介绍如何使用 EasyExcel 实现 Excel 导入功能&#xff0c;以及一些相关的技巧和注…