Skip to content

Latest commit

 

History

History
80 lines (63 loc) · 1.77 KB

567.permutation-in-string.md

File metadata and controls

80 lines (63 loc) · 1.77 KB

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

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

示例1:

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

示例2:

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

注意:

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

滑动窗口

用哈希表记录窗口中各个字符出现次数的差值

  • 正数表示还应该出现几次
  • 0 表示正好
  • 负数表示多出现了几次

代码实现

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char, int> mp;
        for (auto &c: s1) mp[c]++; // 记录 出现次数的差值

        int l = 0, r = 0;
        while (r < s2.size()){
            char c = s2[r++];
            mp[c]--; // 入窗
            while (l < r && mp[c] < 0){ // 出窗
                mp[s2[l++]] ++;
            }
            if (r - l == s1.size()) return true;
        }
        return false;
    }
};
class Solution {
    public boolean checkInclusion(String s1, String s2) {
        HashMap<Character, Integer> wind = new HashMap<>();

        for (Character c : s1.toCharArray()) {
            wind.put(c, wind.getOrDefault(c, 0) + 1);
        }
        int l = 0, r = 0;

        while (r < s2.length()) {
            char c = s2.charAt(r);
            wind.put(c, wind.getOrDefault(c, 0) - 1);
            r++;
            while (l < r && wind.get(c) < 0) {
                wind.put(s2.charAt(l), wind.get(s2.charAt(l)) + 1);
                l++;
            }
            if (r -l == s1.length()) return true;
        }
        return false;
    }
}