关于滑动窗口算法--最小替换字串长度

个人觉得日常遇到的关于滑动窗口的算法题主要分两种:

固定窗口大小的滑动窗口

在固定窗口大小的滑动窗口问题中,窗口的大小是预先定义好的,不会改变。这种类型的问题是相对简单的,因为一旦确定了窗口的大小,就可以直接遍历数组或列表,每次移动窗口一个元素的位置。常见的问题包括:

  1. 最大/最小子数组和:给定一个数组和一个固定大小的窗口,找到所有可能的窗口的最大/最小和。
  2. 窗口内元素的统计:例如,统计窗口内奇数或偶数元素的数量。
  3. 窗口内元素的频率统计:统计窗口内每个元素出现的次数。

解决这类问题的关键在于维护窗口内的状态,以便在窗口滑动时能够快速更新状态。通常可以使用队列、双端队列(deque)或哈希表来维护窗口内的状态。

动态窗口大小的滑动窗口

动态窗口大小的滑动窗口问题则更为复杂,因为窗口的大小不是固定的,而是根据某些条件动态变化的。这类问题通常涉及到在窗口内寻找满足特定条件的子数组或子串。常见的问题包括:

  1. 无重复字符的最长子串:找到最长的不包含重复字符的子串。
  2. 包含所有字符的最短子串:给定一个字符串和一个字符集合,找到包含所有字符集合中字符的最短子串。
  3. 滑动窗口内的特定条件:例如,找到窗口内所有元素的乘积小于等于给定值的最大窗口。

解决这类问题的关键在于如何高效地扩展和收缩窗口,同时维护窗口内的状态。常用的数据结构包括:

  • 双端队列(deque):用于维护窗口内元素的顺序,以便快速找到窗口的边界。
  • 哈希表:用于快速查找和更新窗口内元素的频率。
  • 前缀和/前缀最大/最小值:用于快速计算窗口内元素的和、最大值或最小值。

在解决动态窗口大小的滑动窗口问题时,通常需要维护一个滑动窗口的左右指针,并根据特定条件来移动这些指针。例如,当窗口内不满足条件时,移动左指针来缩小窗口;当窗口内满足条件但需要寻找更优解时,移动右指针来扩展窗口。一般常见的是右指针实现扩张,通过扩张不断找到符合要求的字符串,然后左指针实现收缩,寻求当前状态下的最小的边界。

下面关于动态的滑动窗口给出题目,感兴趣的可以看下(掘金链接):最小替换子串长度 - MarsCode

问题描述

小F得到了一个特殊的字符串,这个字符串只包含字符A、S、D、F,其长度总是4的倍数。他的任务是通过尽可能少的替换,使得A、S、D、F这四个字符在字符串中出现的频次相等。求出实现这一条件的最小子串长度。


测试样例

样例1:

输入:input = "ADDF"

输出:1

样例2:

输入:input = "ASAFASAFADDD"

输出:3

样例3:

输入:input = "SSDDFFFFAAAS"

输出:1

样例4:

输入:input = "AAAASSSSDDDDFFFF"

输出:0

样例5:

输入:input = "AAAADDDDAAAASSSS"

输出:4

求解代码:

java 复制代码
public class Main {
    public static int solution(String input) {
        //这是一个很久之前遗留的问题,代码的第一步,清除我的原来的依托的代码,不得不否认,现在也是依托
        if(input.length() < 4){
            return input.length();
        }

        int[] target = get(input);
        int[] window = new int[4];
        int left = 0, right = 0;
        int minLength = input.length();

        while (right < input.length()) {
            // 扩展窗口
            char ch = input.charAt(right);
            switch (ch) {
                case 'A' -> window[0]++;
                case 'S' -> window[1]++;
                case 'D' -> window[2]++;
                case 'F' -> window[3]++;
            }
            right++;

            // 检查窗口是否满足条件
            while (isValidWindow(window, target)) {
                minLength = Math.min(minLength, right - left);
                if(minLength == 0){
                    return 0;
                }
                // 缩小窗口
                char leftChar = input.charAt(left);
                switch (leftChar) {
                    case 'A' -> window[0]--;
                    case 'S' -> window[1]--;
                    case 'D' -> window[2]--;
                    case 'F' -> window[3]--;
                }
                left++;
            }
        }
        return minLength;
    }

    public static boolean isValidWindow(int[] window, int[] target) {
        for (int i = 0; i < 4; i++) {
            if ( target[i] > 0 && window[i] < target[i]) {
                return false;
            }
        }
        return true;
    }

    public static int[] get(String input){
        int len = input.length() / 4;
        int[] result = new int[4];
        for(int i = 0;i < input.length(); i++){
            char ch = input.charAt(i);
            switch (ch) {
                case 'A' -> result[0]++;
                case 'S' -> result[1]++;
                case 'D' -> result[2]++;
                case 'F' -> result[3]++;
            }
        }
        for(int i = 0; i < 4; i++){
            result[i] = result[i] - len;
        }
        return result;
    }

    public static void main(String[] args) {
        //  You can add more test cases here
        System.out.println(solution("ADDF") == 1);
        System.out.println(solution("ASAFASAFADDD") == 3);
    }
}
相关推荐
强哥聊算力2 小时前
《算力江湖·英伟达传奇》第七集:ChatGPT出现前夜,英伟达发生了什么?
服务器·人工智能·算法·ai·chatgpt·gpu算力
哦虎!4 小时前
【JavaEE】网络初识
java
for_ever_love__5 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
我是人✓6 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡6 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
Navigator_Z6 小时前
LeetCode //C - 1289. Minimum Falling Path Sum II
c语言·算法·leetcode
CCblandy6 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
IT研究室6 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项6 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog6 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友