LeetCode.438 找到字符串中所有字母异位词题解

本文详细介绍了如何使用滑动窗口算法在LeetCode问题438中寻找字符串中的所有字母异位词,包括思路解析、代码实现以及时间复杂度分析。
摘要由CSDN通过智能技术生成

LeetCode.438 找到字符串中所有字母异位词题解


滑动窗口+优化判断解法(Java 执行用时:4ms,击败98.73%)

题目描述

在这里插入图片描述

示例

在这里插入图片描述

思路

  1. 在字符串 s s s中查找字符串 p p p的字母异位词,所以滑动窗口大小固定为 p p p的长度。
  2. 用 int[26] 记录 p p p的字母个数与滑动窗口中字母个数的状态,int diff表示滑动窗口中词与字符串 p p p的差异,值最大为字符串 p p p的长度。

解题方法

  1. m m m = 字符串sss的长度, n n n = 字符串 p p p的长度, r e s res res是返回结果的列表
  2. 如果 m m m小于 n n n,则返回空列表。
  3. 首先,用 int[26] 记录字符串 p p p中字母的数量,每遇到一个字母就在数组中对应位置减 1 1 1
  4. 设滑动窗口初始位置, l e f t = 0 left=0 left=0 l = n − 1 l=n−1 l=n1,将窗口中字符记录入数组中,每遇到一个字母就在对应位置加 1 1 1,如果某一个位置的值大于 0 0 0,说明统计的这个字符是多余的,diff加 1 1 1。最终,如果 d i f f = 0 diff=0 diff=0,则 l e f t = 0 left=0 left=0是一个满足条件的位置,加入 r e s res res
  5. 滑动窗口的左边界向右移动, l e f t + = 1 left+=1 left+=1,删除掉 l e f t − 1 left−1 left1位置的字符,加入 l e f t + l left+l left+l位置的字符。从数组中删除 l e f t − 1 left−1 left1位置的字符后,如果数组中对应位置的值小于 0 0 0,说明与字符串 p p p相比,缺失了对应位置的字符,所以 d i f f diff diff 1 1 1
  6. 判断 d i f f = = 0 diff==0 diff==0,如果等于 0 0 0,则该窗口满足条件,将 l e f t left left加入 r e s res res

复杂度

  1. 时间复杂度: O ( n + m + Σ ) O(n+m+Σ) O(n+m+Σ)
  2. 空间复杂度: O ( Σ ) O(Σ) O(Σ)

Code

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int m = s.length(), n = p.length();
        List<Integer> res = new ArrayList<>();
        if (m < n){
            return new ArrayList<Integer>();
        }
        int diff = 0;
        int[] vocab = new int[26];
        for (char c : p.toCharArray()){
            vocab[c - 'a'] -= 1;
        }
        int left = 0, l = n-1;
        char[] arr = s.toCharArray();
        for (int i = left ; i <= left + l ; i++){
            int index = arr[i] - 'a';
            vocab[index] += 1;
            if (vocab[index] > 0){
                diff++;
            }
        }
        if (diff == 0){
            res.add(left);
        }
        left += 1;
        while (left + l < m){
            int remove = arr[left-1] - 'a', insert = arr[left + l] - 'a';
            if (remove == insert){
                if (diff == 0){
                    res.add(left);
                }
                left++;
                continue;
            }
            if (vocab[remove] <= 0){
                diff++;
            }
            vocab[remove]--;
            if (vocab[insert] < 0){
                diff--;
            }
            vocab[insert]++;
            if (diff == 0){
                res.add(left);
            }
            left++;
        }
        return res;
    }
}

作者:兔君
链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/solutions/2587908/hua-dong-chuang-kou-you-hua-pan-duan-jie-qzae/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值