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;
    }
}
相关推荐
XWalnut4 小时前
LeetCode刷题 day4
算法·leetcode·职场和发展
旖-旎5 小时前
分治(库存管理|||)(4)
c++·算法·leetcode·排序算法·快速选择算法
Kk.08027 小时前
力扣 LCR 084.全排列||
算法·leetcode·职场和发展
旖-旎7 小时前
分治(快速选择算法)(3)
c++·算法·leetcode·排序算法·快速选择
_日拱一卒8 小时前
LeetCode:合并区间
算法·leetcode·职场和发展
派大星~课堂12 小时前
【力扣-21. 合并两个有序链表 ✨】Python笔记
python·leetcode·链表
灰色小旋风12 小时前
力扣删除有序数组中的重复项C++
算法·leetcode·职场和发展
小肝一下12 小时前
每日两道力扣,day3
c++·算法·leetcode·职场和发展
派大星~课堂13 小时前
【力扣-19. 删除链表的倒数第n个节点 ✨】Python笔记
python·leetcode·链表
memcpy013 小时前
LeetCode 1208. 尽可能使字符串相等【不定长滑窗,字符串】1497
算法·leetcode·职场和发展