567. 字符串的排列

题目描述:

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

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

示例1:

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

示例2:

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

注意:

输入的字符串只包含小写字母
两个字符串的长度都在 [1, 10,000] 之间

 

 

思想:滑动窗口

整体思想与LeetCode 76 相同,只是在滑动left时有些区别

参考:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/solution/hua-dong-chuang-kou-tong-yong-si-xiang-jie-jue-zi-/

代码:

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        int left = 0,right = 0,valid = 0;
        unordered_map<char,int> need,window;
        for(auto c:s1)
            need[c]++;
        while(right<s2.size()){
            char c = s2[right];
            right++;
            if(need.count(c)){
                window[c]++;
                if(window[c] == need[c])
                    valid++;
            }
            while(right - left >= s1.size()){  //移动 left 缩小窗口的时机是窗口大小大于 s1.size() 时,对于排列,长度应该是一样
                if(valid == need.size()){  //说明窗口中就是一个合法的排列,所以立即返回 true
                    return true;
                }
                char d = s2[left];
                left++;
                if(need.count(d)){
                    if(window[d] == need[d])   //此时left右移,如果window[d]和need[d]相等,则left右移后valid应减一
                        valid--;
                    window[d]--;
                }
            }
        }
        return false;
    }
};

 

posted @ 2020-05-09 15:02  thefatcat  阅读(193)  评论(0编辑  收藏  举报