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 循环:

第一次移除 s[left] 即 'a',left 变为 1,HashSet 变为 {b, c},此时 'b' 仍然在集合中。第二次继续循环,移除 s[left] 即 '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;
    }
}
相关推荐
不想看见4042 小时前
Add Strings数字处理--力扣101算法题解笔记
数据结构·算法·leetcode
初次攀爬者3 小时前
力扣解题-74. 搜索二维矩阵
算法·leetcode
luckycoding3 小时前
739. 每日温度
算法·leetcode·职场和发展
重生之后端学习4 小时前
152. 乘积最大子数组
数据结构·算法·leetcode·职场和发展·动态规划
Trouvaille ~5 小时前
【递归、搜索与回溯】专题(八):记忆化搜索——从暴力递归到动态规划的桥梁
c++·算法·leetcode·青少年编程·面试·蓝桥杯·动态规划
Sincerelyplz5 小时前
【LeetForge】我用AI写了一个 LeetCode 刷题自动追踪工具,从此告别手动打卡
leetcode·cursor
无尽的罚坐人生5 小时前
hot 100 543. 二叉树的直径
数据结构·算法·leetcode
WolfGang0073215 小时前
代码随想录算法训练营 Day07 | 字符串 part01
数据结构·算法·leetcode