剑指 Offer II 014. 字符串中的变位词

234 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

一、题目描述:

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的某个变位词。

换句话说,第一个字符串的排列之一是第二个字符串的 子串 。

 

示例 1:

输入: s1 = "ab" s2 = "eidbaooo" 输出: True 解释: s2 包含 s1 的排列之一 ("ba"). 示例 2:

输入: s1= "ab" s2 = "eidboaoo" 输出: False  

提示:

1 <= s1.length, s2.length <= 104 s1 和 s2 仅包含小写字母

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/MP…

二、思路分析:

由于本题仅包含小写字母,所以我们维护一个长度为26的数组,使用数组index对应的value值对应a-z字符出现的次数。

使用count[26]数组来记录 s1 中对应字符的出现次数。 设定一个窗口,窗口的大小和 s1 的长度相同,每次窗口向右移,将对应的count[26]字符出现次数-1, 同时将左边移出一个元素,并在count[26]对应字符出现次数+1。 移动完窗口后,判断count[26]数组是不是全为0,若全为0,则表示在 s2 中找到了 s1 的变位词,直接返回true,否则继续滑动窗口。 每次窗口滑动,都需要遍历一次,记录字符次数的数组,如果全部都为0,这表示s2中存在s1的交换词

三、AC 代码:

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if(s1.length() > s2.length()) return false; 
        int left = 0, right = 0;
        int[] count = new int[26];  
        while (right < s1.length()) {
            count[s1.charAt(right) - 'a']++;
            count[s2.charAt(right) - 'a']--;
            right++;
        }
        if(allZero(count)) return true;
        while (right < s2.length()){
            count[s2.charAt(right++) - 'a']--;
            count[s2.charAt(left++) - 'a']++;
            // 
            if(allZero(count)) return true;
        }
        return false;
    }
    private boolean allZero(int[] arr){
        for(int num : arr){
            if(num != 0)
                return false;
        }
        return true;
    }
}

四、总结:

image.png 写题解不易,若对你有帮助,点赞评论再走吧。ヽ(✿゚▽゚)ノ,如有不足,请大家斧正。