Hot100之子串

news2025/2/3 1:13:04

560和为K的子数组

题目

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数

子数组是数组中元素的连续非空序列

思路解析

ps:我们的presum【0】就是0,如果没有这个0的话我们的第一个元素就无法减去上一个元素,为了让我们的第一个元素也能参与前缀和减法,所以我们的presum【0】就是0

我们首先收集前缀和

然后我们两个for循环,里面前缀和作差

然后count++收集答案

代码

class Solution {
    public int subarraySum(int[] nums, int k) {

        //前缀和数组
        int[] presum = new int[nums.length+1];
        for (int i = 0; i < nums.length; i++) {
            //这里需要注意,我们的前缀和是presum[1]开始填充的
            presum[i+1] = nums[i] + presum[i];
        }
        
        //统计个数
        int count = 0;
        for (int i = 0; i < nums.length; ++i) {
            for (int j = i; j < nums.length; ++j) {
                //注意偏移,因为我们的nums[2]到nums[4]等于presum[5]-presum[2]
                //所以这样就可以得到nums[i,j]区间内的和
                if (presum[j+1] - presum[i] == k) {
                    count++;
                }
                
            }
        }
        return count;

    }
}


239滑动窗口的最大值

题目

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位

思路解析

简单的单调栈+滑动窗口思想

我们维护栈内单调递减就行

当里面元素个数大于K的时候,我们就弹出第一个元素就好了

代码

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Integer> deque = new ArrayDeque<>();
        int n = nums.length;

        // 初始化收集结果的数组
        int result[] = new int[n - k + 1];

        for (int i = 0; i < n; i++) {
            // 入
            while (!deque.isEmpty() && nums[deque.getLast()] <= nums[i]) {
                deque.removeLast(); // 维护q的单调性
            }

            deque.addLast(i); // 入队,这是把我们的下标给存进去

            if (i - deque.getFirst() >= k) {
                // 这个是我们的队首已经离开窗口了
                deque.removeFirst();
            }

            // 收集我们的答案
            if (i >= k - 1) {
                result[i - k + 1] = nums[deque.getFirst()];
            }
        }

        return result;
    }
}

前置知识--209长度最小的子数组

题目

思路解析

不断缩小左端点

代码

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0, right = 0, n = nums.length;
        int min = Integer.MAX_VALUE;

        int sum = 0;

        while (right < n) {
            sum += nums[right];
            while (sum >= target) {
                min = Math.min(min, right - left + 1);
                sum -= nums[left];
                left++;
            }
            right++;
        }

        return min == Integer.MAX_VALUE ? 0 : min;
    }
}

76最小覆盖子串

题目

去看上一节的前置知识先

思路解析

字符数组的含义

我们把子串变成字符数组,父串变成字符数组

数组的逻辑是,我们遍历字符串,对特定的字符进行计数,也就是++

        char[] SChar = s.toCharArray();//子串的数组
        int m=s.length();//子串的长度
        int ansLeft=-1;
        int ansRight=m;

        int[] cntS=new int[128];//s子串的字母出现次数,s是子串
        int[] cntT=new int[128];//t字符串中字母出现的次数,t是父串
        
        //对父串中的字符的值进行初始化
        for(char c:t.toCharArray()){
            cntT[c]++;
        }
涵盖函数

然后我们弄个涵盖函数,判断当前字符串是否涵盖

如果父串里面的字符比子串多,我们返回false,说明这个子串没有涵盖父串的所有字符

如果子串里的字符数量都比子串多,那么说明这个子串没问题,这个子串涵盖了父串中的所有字符

 //如果父串里面的字符比子串多,我们返回false,说明这个子串并没有涵盖父串的所有字符
    //如果子串里的字符数量都比子串多,那么说明这个子串没问题,这个子串涵盖了父串中的所有字符
    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;
    }
滑动窗口思想

我们遍历子串,操作子串

子串进入数组,然后根据我们的涵盖函数

如果涵盖+找到了更短的子串,那我们就计算最短长度然后记住left和right

然后弹出最左侧元素,也就是left++进行我们的滑动窗口的收缩

int left=0;

        for(int right=0;right<m;right++){//移动子串右端点
            cntS[SChar[right]]++;//右端点字母进入子串
            while(isCovered(cntS,cntT)){//涵盖

                if(right-left<ansRight-ansLeft){//找到了更短的子串
                    ansLeft=left;
                    ansRight=right;

                }

                cntS[SChar[left]]--;//左端点字母移出子串
                left++;

            }
        }

        return ansLeft<0?"":s.substring(ansLeft,ansRight+1);
为什么ansLeft要初始化成-1?

因为我们要是初始化成0的话,我们并不能判断是否找到了满足条件的子串,因为我们的最终的return函数是根据0来判断,我们是否移动了指针(即是否找到了一个满足条件的子串)

看看我们的return

  return ansLeft<0?"":s.substring(ansLeft,ansRight+1);

代码

class Solution {
    public String minWindow(String s, String t) {
        
        char[] SChar = s.toCharArray();//子串的数组
        int m=s.length();//子串的长度
        int ansLeft=-1;
        int ansRight=m;

        int[] cntS=new int[128];//s子串的字母出现次数,s是子串
        int[] cntT=new int[128];//t字符串中字母出现的次数,t是父串
        
        //对父串中的字符的值进行初始化
        for(char c:t.toCharArray()){
            cntT[c]++;
        }

        int left=0;

        for(int right=0;right<m;right++){//移动子串右端点
            cntS[SChar[right]]++;//右端点字母进入子串
            while(isCovered(cntS,cntT)){//涵盖

                if(right-left<ansRight-ansLeft){//找到了更短的子串
                    ansLeft=left;
                    ansRight=right;

                }

                cntS[SChar[left]]--;//左端点字母移出子串
                left++;

            }
        }

        return ansLeft<0?"":s.substring(ansLeft,ansRight+1);

    }


    //如果父串里面的字符比子串多,我们返回false,说明这个子串并没有涵盖父串的所有字符
    //如果子串里的字符数量都比子串多,那么说明这个子串没问题,这个子串涵盖了父串中的所有字符
    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;
    }
}

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

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

相关文章

网络工程师 (11)软件生命周期与开发模型

一、软件生命周期 前言 软件生命周期&#xff0c;也称为软件开发周期或软件开发生命周期&#xff0c;是指从软件项目的启动到软件不再被使用为止的整个期间。这个过程可以细分为多个阶段&#xff0c;每个阶段都有其特定的目标、任务和产出物。 1. 问题定义与需求分析 问题定义…

(三)QT——信号与槽机制——计数器程序

目录 前言 信号&#xff08;Signal&#xff09;与槽&#xff08;Slot&#xff09;的定义 一、系统自带的信号和槽 二、自定义信号和槽 三、信号和槽的扩展 四、Lambda 表达式 总结 前言 信号与槽机制是 Qt 中的一种重要的通信机制&#xff0c;用于不同对象之间的事件响…

hot100_21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&#xff1a;[…

安全防护前置

就业概述 网络安全工程师/安全运维工程师/安全工程师 安全架构师/安全专员/研究院&#xff08;数学要好&#xff09; 厂商工程师&#xff08;售前/售后&#xff09; 系统集成工程师&#xff08;所有计算机知识都要会一点&#xff09; 学习目标 前言 网络安全事件 蠕虫病毒--&…

01-六自由度串联机械臂(ABB)位置分析

ABB工业机器人&#xff08;IRB2600&#xff09;如下图所示&#xff08;d1444.8mm&#xff0c;a1150mm&#xff0c;a2700mm&#xff0c;a3115mm&#xff0c;d4795mm&#xff0c;d685mm&#xff09;&#xff0c;利用改进DH法建模&#xff0c;坐标系如下所示&#xff1a; 利用改进…

JVM运行时数据区域-附面试题

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域 有各自的用途&#xff0c;以及创建和销毁的时间&#xff0c;有的区域随着虚拟机进程的启动而一直存在&#xff0c;有些区域则是 依赖用户线程的启动和结束而建立和销毁。 1. 程序计…

HTML(快速入门)

欢迎大家来到我的博客~欢迎大家对我的博客提出指导&#xff0c;有错误的地方会改进的哦~点击这里了解更多内容 目录 一、前言二、HTML基础2.1 什么是HTML?2.2 认识HTML标签2.2.1 HTML标签当中的基本结构2.2.2 标签层次结构 2.3 HTML常见标签2.3.1 标题标签2.3.2 段落标签2.3.3…

《苍穹外卖》项目学习记录-Day10订单状态定时处理

利用Cron表达式生成器生成Cron表达式 1.处理超时订单 查询订单表把超时的订单查询出来&#xff0c;也就是订单的状态为待付款&#xff0c;下单的时间已经超过了15分钟。 //select * from orders where status ? and order_time < (当前时间 - 15分钟) 遍历集合把数据库…

AJAX综合案例——图书管理

黑马程序员视频地址&#xff1a; AJAX-Day02-10.案例_图书管理AJAX-Day02-10.案例_图书管理_总结_V1.0是黑马程序员前端AJAX入门到实战全套教程&#xff0c;包含学前端框架必会的&#xff08;ajaxnode.jswebpackgit&#xff09;&#xff0c;一套全覆盖的第25集视频&#xff0c…

30.Word:设计并制作新年贺卡以及标签【30】

目录 NO1.2 NO3邮件合并-信函 NO4邮件合并-标签​ NO1.2 另存为/F12&#xff1a;考生文件夹&#xff1a;Word.docx布局→页面设置对话框→页边距&#xff1a;上下左右→纸张&#xff1a;宽度/高度&#xff08;先调页边距&#x1f197;&#xff09;设计→页面颜色→填充效果→…

Nginx开发01:基础配置

一、下载和启动 1.下载、使用命令行启动&#xff1a;Web开发&#xff1a;web服务器-Nginx的基础介绍&#xff08;含AI文稿&#xff09;_nginx作为web服务器,可以承担哪些基本任务-CSDN博客 注意&#xff1a;我配置的端口是81 2.测试连接是否正常 访问Welcome to nginx! 如果…

数据分析系列--⑨RapidMiner训练集、测试集、验证集划分

一、数据集获取 二、划分数据集 1.导入和加载数据 2.数据集划分 2.1 划分说明 2.2 方法一 2.3 方法二 一、数据集获取 点击下载数据集 此数据集包含538312条数据. 二、划分数据集 1.导入和加载数据 2.数据集划分 2.1 划分说明 2.2 方法一 使用Filter Example Range算子. …

C基础寒假练习(6)

一、终端输入行数&#xff0c;打印倒金字塔 #include <stdio.h> int main() {int rows;printf("请输入倒金字塔的行数: ");scanf("%d", &rows);for (int i rows; i > 0; i--) {// 打印空格for (int j 0; j < rows - i; j) {printf(&qu…

mysqldump+-binlog增量备份

注意&#xff1a;二进制文件删除必须使用help purge 不可用rm -f 会崩 一、概念 增量备份&#xff1a;仅备份上次备份以后变化的数据 差异备份&#xff1a;仅备份上次完全备份以后变化的数据 完全备份&#xff1a;顾名思义&#xff0c;将数据完全备份 其中&#xff0c;…

玩转大语言模型——使用langchain和Ollama本地部署大语言模型

系列文章目录 玩转大语言模型——使用langchain和Ollama本地部署大语言模型 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 玩转大语言模型——使用GraphRAGOllama构建知识图谱 玩转大语言模型——完美解决Gra…

抖♬♬__ac_signature 算法逆向分析

和网页端一样&#xff0c;算法没有问题

网络编程套接字(中)

文章目录 &#x1f34f;简单的TCP网络程序服务端创建套接字服务端绑定服务端监听服务端获取连接服务端处理请求客户端创建套接字客户端连接服务器客户端发起请求服务器测试单执行流服务器的弊端 &#x1f350;多进程版的TCP网络程序捕捉SIGCHLD信号让孙子进程提供服务 &#x1…

CodeForces 611:New Year and Domino ← 二维前缀和

【题目来源】 https://codeforces.com/contest/611/problem/C 【题目描述】 They say "years are like dominoes, tumbling one after the other". But would a year fit into a grid? I dont think so. Limak is a little polar bear who loves to play. He has r…

十分钟快速上手 markdown

前言 本人利用寒假期间&#xff0c;将自己所学的markdown的知识&#xff0c;以及将自己常用的一些操作和注意事项记录下来&#xff0c;希望能够帮助大家 一、markdown是什么 Markdown 是一种轻量级标记语言&#xff0c;说白了就是可以让你利用最简单的语法达到最好的排版效果…

vue2项目(一)

项目介绍 电商前台项目 技术架构&#xff1a;vuewebpackvuexvue-routeraxiosless.. 封装通用组件登录注册token购物车支付项目性能优化 一、项目初始化 使用vue create projrct_vue2在命令行窗口创建项目 1.1、脚手架目录介绍 ├── node_modules:放置项目的依赖 ├──…