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;
    }
}
相关推荐
田梓燊12 小时前
力扣:23.合并 K 个升序链表
算法·leetcode·链表
6Hzlia19 小时前
【Hot 100 刷题计划】 LeetCode 141. 环形链表 | C++ 哈希表直觉解法
c++·leetcode·链表
北顾笙98021 小时前
day35-数据结构力扣
数据结构·算法·leetcode
ulias2121 天前
leetcode热题 - 4
算法·leetcode·职场和发展
圣保罗的大教堂1 天前
leetcode 1559. 二维网格图中探测环 中等
leetcode
_日拱一卒1 天前
LeetCode:148排序链表
算法·leetcode·链表
生信研究猿1 天前
leetcode 78.子集
算法·leetcode·深度优先
浅念-1 天前
分治算法专题|LeetCode高频经典题目详细题解
数据结构·c++·算法·leetcode·职场和发展·排序·分治
shehuiyuelaiyuehao1 天前
算法11,滑动窗口,最大连续1的个数|||
算法·leetcode·职场和发展
脱氧核糖核酸__1 天前
LeetCode热题100——206.反转链表(迭代法)
c++·leetcode·链表