leetcode-hot100-滑动窗口:3无重复字符的最长字串-438找到字符串中所有字母异位词

3无重复字符的最长字串

题目:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。

示例 1: 输入: s = "abcabcbb",输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。注意 "bca" 和 "cab" 也是正确答案。

java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Set<Character> set=new HashSet<>();
        int left=0;
        int maxlen=0;
        for(int right=0;right<s.length();right++){
            char c=s.charAt(right);
            while(set.contains(c)){
                set.remove(s.charAt(left));
                left++;
            }
            set.add(c);
            maxlen=Math.max(maxlen,right-left+1);
        }

        return maxlen;
    }
}

注意是while:

例如,在字符串 "abcba" 中,当右指针指向第二个 'b' 时,窗口内是 "abc"(假设 left=0, right=3)。此时 HashSet 中有 {a, b, c},新字符 'b' 重复。我们开始 while 循环:

第一次移除 sleft 即 'a',left 变为 1,HashSet 变为 {b, c},此时 'b' 仍然在集合中。第二次继续循环,移除 sleft 即 'b',left 变为 2,HashSet 变为 {c},此时 'b' 不再重复,循环结束。可见,我们需要多次移除才能把旧的 'b' 赶出窗口。如果只用 if,只移除一次是不够的。

滑动窗口的模板:

java 复制代码
//外层循环扩展右边界,内层循环扩展左边界
for (int l = 0, r = 0 ; r < n ; r++) {
	//当前考虑的元素
	while (l <= r && check()) {//区间[left,right]不符合题意
        //扩展左边界
    }
    //区间[left,right]符合题意,统计相关信息
}

438找到字符串中所有字母异位词

题目:给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

示例 1:输入: s = "cbaebabacd", p = "abc"

输出: 0,6

解释:起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。

起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

java 复制代码
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> result=new ArrayList<>();
        int slen=s.length();
        int plen=p.length();

        if(slen<plen) return result;

        int[] pcount=new int[26]; // 统计 p 中每个字符的出现次数
        for(char c:p.toCharArray()){
            pcount[c-'a']++;
        }

        int[] window=new int[26]; // 初始化窗口
        for(int i=0;i<plen;i++){
            window[s.charAt(i)-'a']++;
        }

        if(Arrays.equals(pcount,window)){
            result.add(0);
        }

        for(int i=plen;i<slen;i++){ //开始移动窗口
            char left=s.charAt(i-plen);
            window[left-'a']--;  // 移出左边字符
            char right=s.charAt(i);
            window[right-'a']++; // 加入右边字符

            if (Arrays.equals(pcount, window)) {  // 比较窗口与 p 的字符计数
                result.add(i - plen + 1);
            }
        }
        return result;
    }
}
相关推荐
tachibana28 分钟前
hot100 前 K 个高频元素(347)
java·数据结构·算法·leetcode
To_OC8 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
旖-旎9 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
To_OC10 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
tachibana220 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode
晚笙coding1 天前
LeetCode 98:验证二叉搜索树 —— 从局部判断到全局范围约束的递归思想
算法·leetcode·职场和发展
兰令水1 天前
hot100【acm版】【2026.7.21打卡-java版本】
java·开发语言·算法·leetcode·面试
退休倒计时1 天前
【每日一题】LeetCode 131. 分割回文串 TypeScript
算法·leetcode·typescript
旖-旎2 天前
LeetCode 279:完全平方数(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
良木林2 天前
滑动窗口 - LeetCode hot 100
javascript·算法·leetcode·双指针·滑动窗口