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

文章目录

  • 剑指 Offer II 014. 字符串中的变位词
    • 题目
    • 题解

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

题目

给定两个字符串 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)
链接:https://leetcode.cn/problems/MPnaiL
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

需要关注的问题
1.s1里有哪些字符出现过
2.s1的字符随机组合之后,在s2中需要连续出现

我们在遍历s1的时候,可以将s1出现过的字符存放在map中。key为字符,value为出现的次数。这里全是小写字母也可以用26位的数组实现。
遍历s2,假设坐标为i,那么此时[i,i+s1.length-1]应该都需要在s1出现过。这样就可以保证连续了。
怎么比较[i,i+s1.length-1]和s1的数组是否一样?可以给s2也创建一个数组,记录窗口中出现过的元素及个数。

var checkInclusion = function(s1, s2) {
 	let s1Arr=new Array(26).fill(0);
 	let s2Arr=new Array(26).fill(0);
    if(s2.length<s1.length)return false;	
    for(let ch of s1){ //记录s1的情况
        s1Arr[ch.charCodeAt()-'a'.charCodeAt()]++;
    }
    let left = 0;
    for(let right = 0; right < s2.length; right ++) {
        s2Arr[s2[right].charCodeAt() - 'a'.charCodeAt(0)] ++; 
        if(right - left + 1 === s1.length) { //当窗口大小刚好合适,比较里面的元素是否相等
            if(s1Arr.toString() === s2Arr.toString()) return true  
        }

        if(right >= s1.length - 1) { //如果窗口大小超过了,说明需要开始收缩了
            s2Arr[s2[left].charCodeAt() - 'a'.charCodeAt()]--;
            left ++;
        }
    }
    return false;
};

你可能感兴趣的:(算法,leetcode,动态规划,算法)