剑指 Offer II 014. 字符串中的变位词(567. 字符串的排列)

题目:

 

思路:

【1】只能说这道题和 【剑指 Offer II 015. 字符串中的所有变位词(438. 找到字符串中所有字母异位词)】是一样的,逻辑都不用改,就该一下参数和返回值就可以了

【2】本质思路:利用滑动窗口加字符集数组的思想

【3】双指针的思路

代码展示:

双指针的思路:

//时间2 ms击败100%
//内存41.1 MB击败85.5%
class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if (s1.length() > s2.length()) return false;
        //s1 和 s2 仅包含小写字母(s1往s2里面查)
        int[] flag1 = new int[26] ;
        for (char ch : s1.toCharArray()){
            flag1[ch - 'a'] -= 1;
        }
        //利用滑动窗口大的思想,窗口大小为s1.length()的大小
        char[] sArr = s2.toCharArray();
        int left = 0;
        for (int right = 0; right < sArr.length; right++){
            int index = sArr[right] - 'a';
            flag1[index]++;
            //这里的理解很关键,因为它的思路是在于刚好这个标志位是0,也就是刚好补了缺了的空,且下面还会判断长度是否满足目标长度
            //如目标为ab,当时b的时候,虽然满足标志位回补,但是长度不符合,
            // 当时c的时候由于标志位大于1,做指针移动,直至回补为0【即左右指针重合】
            while (flag1[index] > 0) {
                flag1[sArr[left] - 'a']--;
                left++;
            }
            if (right - left + 1 == s1.length()) return true;
        }

        return false;
    }
}

 

利用滑动窗口加字符集数组的思想:

//时间4 ms击败84.21%
//内存41.5 MB击败45.1%
class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if (s1.length() > s2.length()) return false;
        //s1 和 s2 仅包含小写字母
        int[] flag1 = new int[26] , flag2 = new int[26];
        for (char ch : s1.toCharArray()){
            flag1[ch - 'a'] += 1;
        }
        //利用滑动窗口大的思想,窗口大小为p.length()的大小
        char[] sArr = s2.toCharArray();
        for (int i = 0; i < s1.length() - 1; i++){
            flag2[sArr[i] - 'a'] += 1;
        }

        for (int i = s1.length() - 1; i < sArr.length; i++){
            flag2[sArr[i] - 'a'] += 1;
            if (Arrays.equals(flag1,flag2)) return true;
            flag2[sArr[i + 1 - s1.length()] - 'a'] -= 1;
        }

        return false;
    }
}

 

posted @ 2023-03-08 15:09  忧愁的chafry  阅读(26)  评论(0)    收藏  举报