每日算法-250329

news2025/4/1 2:05:49

记录今天学习的三道算法题:两道滑动窗口和一道栈的应用。


2904. 最短且字典序最小的美丽子字符串

题目描述
Problem 2904 Description

思路

滑动窗口

解题过程

题目要求找到包含 k 个 ‘1’ 的子字符串,并且需要满足两个条件:

  1. 最短长度:在所有包含 k 个 ‘1’ 的子字符串中,长度最小。
  2. 字典序最小:如果存在多个长度最短的子字符串,选择字典序最小的那个。

我们可以使用滑动窗口来解决这个问题。维护一个窗口 [left, right],以及窗口内 ‘1’ 的计数 count

  1. 扩展窗口:移动 right 指针向右扩展窗口。如果 s[right] 是 ‘1’,则 count 增加。
  2. 检查与收缩窗口:当 count 达到 k 时,当前窗口 [left, right] 就包含恰好 k 个 ‘1’ 了吗?不一定,可能 count > k。 我们需要一个 while 循环,count >= k
    • 找到有效子串:如果 count == k,此时窗口 [left, right] 是一个包含 k 个 ‘1’ 的有效子字符串。我们计算其长度 len = right - left + 1
    • 更新结果
      • 如果 len 小于当前记录的最短长度 retLen,则更新 retLen = len,并将当前子字符串 s.substring(left, right + 1) 存为 retString
      • 如果 len 等于 retLen,则比较当前子字符串 s.substring(left, right + 1)retString 的字典序,如果当前子字符串字典序更小,则更新 retString
    • 收缩窗口:为了寻找可能更短的或者字典序更小的有效子串(或者单纯为了让窗口继续滑动),我们需要移动 left 指针向右收缩窗口。如果滑出窗口的字符 s[left] 是 ‘1’,则 count 减少。然后 left++
  3. 循环与结束right 指针遍历完整个字符串后结束。
  4. 返回结果:如果 retLen 仍然是初始值 n + 1,说明没有找到包含 k 个 ‘1’ 的子字符串,返回空字符串 "";否则返回 retString

复杂度

  • 时间复杂度: O ( n ) O(n) O(n) - 每个字符最多进出窗口一次。字符串比较在最坏情况下可能达到 O ( n ) O(n) O(n),但均摊下来,总复杂度仍接近 O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1) - 只使用了常数级别的额外空间(不算存储结果字符串的空间)。

Code

class Solution {
    public String shortestBeautifulSubstring(String s, int k) {
        String retString = "";
        int n = s.length();
        
        int retLen = n + 1;
        int count = 0;

        for (int left = 0, right = 0; right < n; right++) {
            char in = s.charAt(right);
            // 进窗口
            if (in == '1') {
                count++;
            }

            // 判断与收缩
            while (count >= k) {
                if (count == k) {
                   int len = right - left + 1;
                   // 更新结果
                   String currentSub = s.substring(left, right + 1);
                   if (len < retLen) {
                       retLen = len;
                       retString = currentSub;
                   } else if (len == retLen) {
                       if (retString.isEmpty() || currentSub.compareTo(retString) < 0) {
                           retString = currentSub;
                       }
                   }
                }

                // 出窗口
                if (s.charAt(left) == '1') {
                    count--;
                }
                left++;
            }
        }

        return (retLen == n + 1) ? "" : retString;
    }
}

209. 长度最小的子数组

题目描述
Problem 209 Description

思路

滑动窗口

解题过程

维护一个滑动窗口 [left, right] 和窗口内元素的和 sum

  1. 扩展窗口right 指针向右移动,将 nums[right] 加入 sum
  2. 检查与收缩窗口:使用 while 循环检查 sum 是否大于等于 target
    • 如果 sum >= target,说明当前窗口 [left, right] 是一个满足条件的子数组。记录其长度 right - left + 1,并更新全局最小长度 ret
    • 收缩窗口:因为题目要求最小长度,并且数组元素都是正数,所以当前窗口已经满足条件后,可以尝试缩短它。将 nums[left]sum 中减去,并将 left 指针右移 (left++)。继续在 while 循环内检查 sum 是否仍然满足 >= target
  3. 循环与结束right 指针遍历完整个数组后结束。
  4. 返回结果:如果 ret 仍然是初始的最大值 Integer.MAX_VALUE,说明没有找到满足条件的子数组,返回 0;否则返回 ret

复杂度

  • 时间复杂度: O ( n ) O(n) O(n) - 每个元素最多进出窗口一次。
  • 空间复杂度: O ( 1 ) O(1) O(1) - 只使用了常数级别的额外空间。

Code

class Solution { 
    public int minSubArrayLen(int target, int[] nums) {
        int ret = Integer.MAX_VALUE;
        int sum = 0;
        int n = nums.length;
        for (int left = 0, right = 0; right < n; right++) {
            // 进窗口
            sum += nums[right];
            // 判断与收缩
            while (sum >= target) {
                // 更新结果
                ret = Math.min(ret, right - left + 1);
                // 出窗口
                sum -= nums[left];
                left++;
            }
        }
        // 返回结果
        return ret == Integer.MAX_VALUE ? 0 : ret;
    }
}

20. 有效的括号

题目描述
Problem 20 Description

思路

栈 (Stack)

解题过程

利用栈的“后进先出”特性来匹配括号。

  1. 遍历字符串:逐个检查字符串中的字符。
  2. 左括号:如果遇到左括号(([{),将其压入栈中。
  3. 右括号:如果遇到右括号()]}):
    • 检查栈是否为空:如果此时栈为空,说明没有对应的左括号与之匹配,字符串无效,返回 false
    • 检查栈顶元素:查看(不弹出)栈顶的左括号 look = stack.peek()
    • 匹配判断:判断当前右括号 in 是否与栈顶左括号 look 匹配。
      • 如果匹配(例如 look == '('in == ')'),则弹出栈顶元素 stack.pop()
      • 如果不匹配,说明括号类型不对应,字符串无效,返回 false
  4. 遍历结束:遍历完整个字符串后:
    • 检查栈是否为空:如果栈为空,说明所有括号都成功匹配,字符串有效,返回 true
    • 如果栈不为空,说明有多余的左括号没有被匹配,字符串无效,返回 false

优化: 可以在开始时检查字符串长度是否为奇数,如果是奇数,则肯定无效,可以直接返回 false

复杂度

  • 时间复杂度: O ( n ) O(n) O(n) - 只需遍历一次字符串。
  • 空间复杂度: O ( n ) O(n) O(n) - 最坏情况下,如果字符串全是左括号,栈的大小会等于字符串长度。

Code

class Solution {
    public boolean isValid(String ss) {
        if (ss == null || ss.length() % 2 != 0) {
            return false;
        }

        Stack<Character> stack = new Stack<>();
        char[] s = ss.toCharArray();

        for (int i = 0; i < s.length; i++) {
            char in = s[i];
            // 左括号入栈 
            if (in == '(' || in == '[' || in == '{') {
                stack.push(in);
            } else {
                // 右括号处理 
                // 栈为空,但遇到右括号 
                if (stack.isEmpty()) {
                    return false;
                }

                char look = stack.peek();
                // 检查是否匹配
                if ((look == '(' && in == ')') ||
                    (look == '[' && in == ']') ||
                    (look == '{' && in == '}')) {
                    stack.pop();
                } else {
                    // 没匹配上
                    return false;
                }
            }
        }

        // 遍历结束后,栈应该是空的
        return stack.isEmpty();
    }
}

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

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

相关文章

向量数据库学习笔记(2) —— pgvector 用法 与 最佳实践

关于向量的基础概念&#xff0c;可以参考&#xff1a;向量数据库学习笔记&#xff08;1&#xff09; —— 基础概念-CSDN博客 一、 pgvector简介 pgvector 是一款开源的、基于pg的、向量相似性搜索 插件&#xff0c;将您的向量数据与其他数据统一存储在pg中。支持功能包括&…

蓝桥杯 之 二分

文章目录 习题肖恩的n次根分巧克力2.卡牌 二分是十分重要的一个算法&#xff0c;常常用于求解一定范围内&#xff0c;找到满足条件的边界值的情况主要分为浮点数二分和整数二分二分问题&#xff0c;最主要是写出这个check函数&#xff0c;这个check函数最主要就是使用模拟的方法…

从零开始研发GPS接收机连载——18、北斗B1的捕获和跟踪

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 从零开始研发GPS接收机连载——18、北斗B1的捕获和跟踪 B1信号的捕获B1信号的跟踪 前面已经验证了射频能够接收到B1的信号&#xff0c;通过FPGA采集了IQ信号之后能够通过matl…

memtest86检测内存

上次在R730安装万兆网卡的时候&#xff0c;使用过memtest64进行测试。这个操作肯定是有用的&#xff0c;我就用这个方法查出有问题的内存条&#xff0c;及时找商家进行了更换。 但是该方案有个问题&#xff0c;只能锁定部分内存&#xff0c;如下图&#xff0c;只测试到了23G左…

验证linux多进程时间片切换的程序

一、软件需求 在同时运行一个或多个一味消耗 CPU 时间执行处理的进程时&#xff0c;采集以下统计信息。 ・在某一时间点运行在逻辑 CPU 上的进程是哪一个 ・每个进程的运行进度 通过分析这些信息&#xff0c;来确认本章开头对调度器的描述是否正确。实验程序的…

【Basys3】外设-灯和数码管

灯 约束文件 set_property PACKAGE_PIN W5 [get_ports CLK] set_property PACKAGE_PIN U18 [get_ports rst] set_property PACKAGE_PIN U16 [get_ports {led[0]}] set_property PACKAGE_PIN E19 [get_ports {led[1]}] set_property PACKAGE_PIN U19 [get_ports {led[2]}] set…

axios文件下载使用后端传递的名称

java后端通过HttpServletResponse 返回文件流 在Content-Disposition中插入文件名 一定要设置Access-Control-Expose-Headers&#xff0c;代表跨域该Content-Disposition返回Header可读&#xff0c;如果没有&#xff0c;前端是取不到Content-Disposition的&#xff0c;可以在统…

从零开始搭建Anaconda环境

Anaconda是一个流行的Python数据科学平台&#xff0c;包含conda包管理器、Python解释器和大量预装的数据科学工具包。以下是详细的安装和配置步骤&#xff1a; 1. 下载Anaconda 访问Anaconda官方网站 根据你的操作系统(Windows/macOS/Linux)选择相应版本 推荐下载Python 3.x版…

基于ssm的课程辅助教学平台(全套)

互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对《离散结构》课程教学信息管理混乱&#xff0c;出错率高&#xff0c;信息安…

[创业之路-344]:战略的本质是选择、聚焦, 是成本/效率/低毛利优先,还是差易化/效益/高毛利优先?无论是成本优先,还是差易化战略,产品聚焦是前提。

前言&#xff1a; 一、战略的本质是选择、聚焦 关于战略的本质&#xff0c;触及了商业竞争的核心矛盾&#xff1a;选择成本优先&#xff08;效率/低毛利&#xff09;还是差异化&#xff08;效益/高毛利&#xff09;&#xff0c;本质上是对企业战略方向的终极拷问。 1、战略选…

Typora 小乌龟 git 上传到gitee仓库教程

首先进行资源分享 通过网盘分享的文件&#xff1a;TortoiseGit-LanguagePack-2.17.0.0-64bit-zh_CN.msi等4个文件 链接: https://pan.baidu.com/s/1NC8CKLifCEH_YixDU3HG_Q?pwdqacu 提取码: qacu --来自百度网盘超级会员v3的分享 首先将软件进行解压 看自己电脑的版本进行…

【新人系列】Golang 入门(八):defer 详解 - 上

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12898955.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Golang 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…

RAG - 五大文档切分策略深度解析

文章目录 切分策略1. 固定大小分割&#xff08;Fixed-Size Chunking&#xff09;2. 滑动窗口分割&#xff08;Sliding Window Chunking&#xff09;3. 自然语言单元分割&#xff08;Sentence/Paragraph Segmentation&#xff09;4. 语义感知分割&#xff08;Semantic-Aware Seg…

keil中文注释出现乱码怎么解决

keil中文注释出现乱码怎么解决 在keil–edit–configuration中encoding改为chinese-GB2312

论文阅读笔记——ReconDreamer

ReconDreamer 论文 在 DriveDreamer4D 的基础上&#xff0c;通过渐进式数据更新&#xff0c;解决大范围机动&#xff08;多车道连续变道、紧急避障&#xff09;的问题。同时 DriveDreamer4D生成轨迹后直接渲染&#xff0c;而 ReconDreamer 会实时通过 DriveRestorer 检测渲染结…

鸿蒙harmonyOS:笔记 正则表达式

从给出的文本中&#xff0c;按照既定的相关规则&#xff0c;匹配出符合的数据&#xff0c;其中的规则就是正则表达式&#xff0c;使用正则表达式&#xff0c;可以使得我们用简洁的代码就能实现一定复杂的逻辑&#xff0c;比如判断一个邮箱账号是否符合正常的邮箱账号&#xff0…

计算机网络——传输层(TCP)

传输层 在计算机网络中&#xff0c;传输层是将数据向上向下传输的一个重要的层面&#xff0c;其中传输层中有两个协议&#xff0c;TCP&#xff0c;UDP 这两个协议。 TCP 话不多说&#xff0c;我们直接来看协议报头。 源/目的端口号&#xff1a;表示数据从哪个进程来&#xff0…

英伟达与通用汽车深化合作,澳特证券am broker助力科技投资

在近期的GTC大会上&#xff0c;英伟达CEO黄仁勋宣布英伟达将与通用汽车深化合作&#xff0c;共同推进AI技术在自动驾驶和智能工厂的应用。此次合作标志着自动驾驶汽车时代的加速到来&#xff0c;同时也展示了英伟达在AI技术领域的最新进展。      合作内容包括&#xff1a;…

CSS学习笔记5——渐变属性+盒子模型阶段案例

目录 通俗易懂的解释 渐变的类型 1、线性渐变 渐变过程 2、径向渐变 如何理解CSS的径向渐变&#xff0c;以及其渐变属性 通俗易懂的解释 渐变属性 1. 形状&#xff08;Shape&#xff09; 2. 大小&#xff08;Size&#xff09; 3. 颜色停靠点&#xff08;Color Sto…

[Java微服务架构]4_服务通信之客户端负载均衡

欢迎来到啾啾的博客&#x1f431;&#xff0c;一个致力于构建完善的Java程序员知识体系的博客&#x1f4da;&#xff0c;记录学习的点滴&#xff0c;分享工作的思考、实用的技巧&#xff0c;偶尔分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604…