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;
    }
}
相关推荐
To_OC10 小时前
LC 994 腐烂的橘子:人人都说是 BFS 入门题,我却写了三遍才过
javascript·算法·leetcode
To_OC16 小时前
LC 200 岛屿数量:经典 DFS 入门题,我第一次写居然连方向都搞错了
javascript·算法·leetcode
To_OC1 天前
LC 128 最长连续序列:别上来就排序,O (n) 解法才是这题的灵魂
javascript·算法·leetcode
To_OC3 天前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
To_OC5 天前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
想吃火锅100511 天前
【leetcode】121.买卖股票的最佳时机js/c++
算法·leetcode·职场和发展
凌波粒11 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
退休倒计时11 天前
【每日一题】LeetCode 146. LRU 缓存 TypeScript
算法·leetcode·缓存·typescript
小欣加油11 天前
leetcode3612 用特殊操作处理字符串I
数据结构·c++·算法·leetcode·职场和发展
凌波粒11 天前
LeetCode--90.子集II(回溯算法)
数据结构·算法·leetcode