力扣-滑动窗口

文章目录

滑动窗口

滑动窗口是一种常用的算法技巧,适用于需要在一个数组或字符串中找出满足特定条件的连续子数组子字符串的问题。它通过维护一个窗口范围来减少重复计算,从而优化算法的时间复杂度

滑动窗口算法通常涉及两个指针,分别表示窗口的左边界右边界。窗口在数组或字符串上滑动,并在滑动过程中动态调整窗口的大小和位置,以满足特定条件。主要步骤如下:

  1. 初始化窗口边界:设置窗口的初始左边界和右边界。
  2. 移动右边界:扩大窗口的右边界,直到窗口内的元素满足特定条件。
  3. 调整左边界:当窗口内的元素满足特定条件时,尝试移动左边界以缩小窗口,同时保持窗口内的元素仍然满足条件。
  4. 记录结果:在每次窗口满足条件时,记录当前窗口的大小或内容。
  5. 重复步骤 2 和 3:直到右边界到达数组或字符串的末尾。

题目1-无重复字符的最长子串

第一种:【第一次接触可能第一种方法容易理解】

java 复制代码
public class Test {
    public static int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        char[] charArray = s.toCharArray();
        int left = 0, right = 0;
        int res = 0;
        while (right < charArray.length) {
            if (map.containsKey(charArray[right])) {
                map.remove(charArray[left]);
                left++;
            } else {
                map.put(charArray[right], 1);
                res = Math.max(res, right - left + 1);
                right++;
            }
        }
        return res;
    }

    public static void main(String[] args) {
        String s = "abcabcbb";
        System.out.println(lengthOfLongestSubstring(s));
    }
}

第二种:可以跳跃式地移动 left 指针

java 复制代码
public class Test {
    public static int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        char[] charArray = s.toCharArray();
        int left = 0, right = 0;
        int res = 0;
        for (; right < s.length(); right++) {
            if (map.containsKey(charArray[right])) {
                left = Math.max(left, map.get(charArray[right]) + 1);
            }
            map.put(charArray[right], right);
            res = Math.max(res, right - left + 1);
        }
        return res;
    }

    public static void main(String[] args) {
        String s = "abcabcbb";
        System.out.println(lengthOfLongestSubstring(s));
    }
}

题目2-找到字符串中所有字母异位词

第一种方法:(不建议,容易超时)

这是我第一想到的方法

java 复制代码
public class Test {

    public static String stringSort(String s) {
        char[] charArray = s.toCharArray();
        Arrays.sort(charArray);
        return new String(charArray);
    }

    public static List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();
        if (s.length() < p.length()) return res;

        String sortedP = stringSort(p);
        int s_len = s.toCharArray().length;
        int p_len = p.toCharArray().length;
        int left = 0, right = 0;
        while (right < s_len) {
            if (right - left + 1 == p_len) {
                if (stringSort(s.substring(left, right + 1)).equals(sortedP)) {
                    res.add(left);
                }
                left++;
                right++;
            } else {
                right++;
            }
        }
        return res;
    }

    public static void main(String[] args) {
        String s = "cbaebabacd", p = "abc";
        System.out.println(findAnagrams(s, p));
    }
}

第二种方法:

java 复制代码
public class Test {
    public static List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();
        if (s.length() < p.length()) return res;

        int p_len = p.length();
        int s_len = s.length();

        int[] pCount = new int[26];
        for (char c : p.toCharArray()) {
            pCount[c - 'a']++;
        }

        int[] sCount = new int[26];
        for (int i = 0; i < s_len; i++) {
            sCount[s.charAt(i) - 'a']++;

            if (i >= p_len) {
                sCount[s.charAt(i - p_len) - 'a']--;
            }

            if (check(pCount, sCount)) {
                res.add(i - p_len + 1);
            }
        }
        return res;
    }

    private static boolean check(int[] pCount, int[] sCount) {
        for (int i = 0; i < 26; i++) {
            if (pCount[i] != sCount[i]) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        String s = "cbaebabacd";
        String p = "abc";
        System.out.println(findAnagrams(s, p));
    }
}

❤觉得有用的可以留个关注~~❤

相关推荐
考虑考虑8 分钟前
Sentinel安装
java·后端·微服务
轻颂呀14 分钟前
约瑟夫环问题
算法
凤凰院凶涛QAQ2 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
科技大视界2 小时前
投资AI项目,传统尽调不够用了——李章虎律师拆解算法、数据、算力三大雷区
人工智能·算法·数据挖掘
郝学胜-神的一滴2 小时前
算法实战:最小k个数——大顶堆的优雅解法
开发语言·数据结构·c++·python·程序人生·算法·排序算法
Irissgwe2 小时前
算法滑动窗口
数据结构·算法
掘金_答案2 小时前
上线那天,一个 ConcurrentHashMap 差点送走我的 AI 客服——3 天排查 JVM 血泪史
java·后端·架构
怪兽学LLM2 小时前
LeetCode 105. 从前序与中序遍历序列构造二叉树:分治递归思路详解
算法·leetcode·职场和发展
可编程芯片开发3 小时前
基于PI控制的三相整流器控制系统的simulink建模与仿真,包含超级电容充电和电机
算法
猿与禅3 小时前
CosId 分布式 ID 生成器完全教程:从架构原理到生产落地
java·shardingsphere·雪花算法·分布式id·高性能·cosid·号段模式