Leetcode Hot100 | Day02 滑动窗口

8、无重复字符的最长子串

3. 无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串的长度。
示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

题解:双指针配合哈希表,使用滑动窗口右指针不断向右移动,遇见相同元素,逐步移除左边元素,在更新的过程中记录当前最长无重复子串的长度

    public int lengthOfLongestSubstring(String s) {
        // 定义一个 HashSet 用来存储当前窗口内的字符
        Set<Character> set = new HashSet<>();

        // 初始化左右指针
        int left = 0;
        int right = 0;

        // 用来记录最长无重复子串的长度
        int max = 0;

        // 使用滑动窗口,右指针不断右移
        while (right < s.length()) {
            // 如果右指针指向的字符不在 set 中,说明当前字符没有重复
            if (!set.contains(s.charAt(right))) {
                // 将字符添加到 set 中,并右移右指针
                set.add(s.charAt(right));
                right++;
            } else {
                // 如果右指针指向的字符已经在 set 中,说明有重复
                // 将左指针指向的字符移出 set 中,左指针右移
                set.remove(s.charAt(left));
                left++;
            }

            // 每次更新 max,记录当前最长无重复子串的长度
            max = Math.max(max, set.size());
        }

        // 返回最大长度
        return max;
    }

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

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

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

题解:解法一:暴力解法
对字符串p进行排序,再依次截取s中p对应长度的字符串进行排序,如果相等,则当前下标i符合要求。

    public static List<Integer> findAnagrams(String s, String p) {
        List<Integer> list = new ArrayList<>();
        String str = strSort(p);
        for(int i = 0; i<s.length()-p.length()+1; i++){
            String res = s.substring(i, i+p.length());
            if(str.equals(strSort(res))){
                list.add(i);
            }
        }
        return list;
    }

    public static String strSort(String str){
        char[] charArray = str.toCharArray();
        Arrays.sort(charArray);
        return new String(charArray);
    }

解法二:用数组哈希表的方式+滑动窗口进行处理;
固定窗口内的哈希数组和p的哈希数组进行判断是否相等;

    public List<Integer> findAnagrams(String s, String p) {
        // 创建一个 list 来存储结果
        List<Integer> list = new ArrayList<>();

        // 创建两个数组用来存储 p 和 s 窗口内字符的频率
        int[] ansP = new int[26]; // p 字符串的频率数组
        int[] ansS = new int[26]; // s 字符串的窗口频率数组

        // 统计 p 字符串中每个字符的频率
        for (char c : p.toCharArray()) {
            ansP[c - 'a']++; // 将字符映射到对应的索引位置,并累加
        }

        // 滑动窗口,右指针逐步向右移动
        for (int right = 0; right < s.length(); right++) {
            // 更新窗口内字符的频率
            ansS[s.charAt(right) - 'a']++;

            // 计算当前窗口的左指针位置
            int left = right - p.length() + 1;

            // 如果左指针位置小于 0,继续循环,确保窗口大小为 p 的长度
            if (left < 0) {
                continue;
            }

            // 比较窗口内字符的频率与 p 的字符频率是否一致
            if (Arrays.equals(ansP, ansS)) {
                // 如果一致,说明窗口内的字符是 p 的字母异位词,记录下左指针的位置
                list.add(left);
            }

            // 移动左指针,将该位置的字符频率减 1
            ansS[s.charAt(left) - 'a']--;
        }

        // 返回结果
        return list;
    }

你可能感兴趣的:(JAVA数据结构与算法,leetcode,算法)