当前位置: 首页 > news >正文

每日算法-250329

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


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.dtcms.com/a/99339.html

相关文章:

  • 注意力蒸馏技术
  • 深度学习处理时间序列(7)
  • Github 2025-03-28 Java开源项目日报Top10
  • 手机硬件检测详解:从版本信息到相机功能的全面指南
  • [Java微服务架构]7-1_事务处理——事务特性与本地事务
  • 【商城实战(101)】电商未来已来:新技术引领商城发展新航向
  • 查看显卡算力
  • 使用LangChain Agents构建Gradio及Gradio Tools(1)——LangChain Agent概念
  • RCE--解法
  • 基于SpringBoot的“医疗设备管理系统”的设计与实现(源码+数据库+文档+PPT)
  • MySQL源码学习系列(一)-- 环境准备及常用命令
  • 【LeetCode】—169.多数元素
  • Java基础-21-基本语法-封装
  • 聚合根的特性
  • CI/CD-Jenkins安装与应用
  • 【网络编程】搭建一个简单的UDP通信服务器和客户端
  • c#winform,倒鸭子字幕效果,typemonkey字幕效果,抖音瀑布流字幕效果
  • uniapp中的流式输出
  • 蓝桥杯 14 天 十五届蓝桥杯 数字诗意
  • 雨云云应用测评!内测持续进行中!
  • 深度学习中常见的专业术语汇总
  • SQL Server 可用性组自动种子设定失败问题
  • .NET开发基础知识1-10
  • 无人机宽带自组网机载电台技术详解,50KM超远图数传输系统实现详解
  • Python控制结构详解
  • 群体智能优化算法-流向算法(Flow Direction Algorithm, FDA,含Matlab源代码)
  • FALL靶机渗透实战:从信息收集到特权升级的完整链分析
  • postgresql 重置对应表序列最大值
  • 药用植物次生代谢的多层调控-文献精读123
  • 如何利用<ruby>、<rt>、<rp>标签实现中文注音或字符注释?