567. Permutation in String
Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string’s permutations is the substring of the second string.
Example 1:
Input: s1 = "ab" s2 = "eidbaooo"
Output: True
Explanation: s2 contains one permutation of s1 ("ba").
Example 2:
Input:s1= "ab" s2 = "eidboaoo"
Output: False
Note:
- The input strings only contain lower case letters.
- The length of both given strings is in range [1, 10,000].
方法1: sliding window + vector
参见438. Find All Anagrams in a String
花花:http://zxi.mytechroad.com/blog/hashtable/leetcode-438-find-all-anagrams-in-a-string/
易错点
- 题目要求是s2 contains s1, 看清楚
Complexity
Time complexity: O(n)
Space complexity: O(n)
class Solution {
public:
bool checkInclusion(string s1, string s2) {
if (s1.empty() || s2.empty() || s1.size() > s2.size()) return false;
int m = s1.size();
int n = s2.size();
vector<int> hash(26, 0);
vector<int> copy(26, 0);
for (char c: s1) hash[c - 'a'] ++;
for (int i = 0; i < n; i++) {
if (i >= m) copy[s2[i - m] - 'a']--;
copy[s2[i] - 'a']++;
if (hash == copy) return true;
}
return false;
}
};
方法2: sliding window (two pointers)+ hash
discussion: https://leetcode.com/problems/permutation-in-string/discuss/102590/8-lines-slide-window-solution-in-Java
思路:
首先建立一下目标string,也就是s1的计数hash,然后开始遍历s2。用左右指针维持一个sliding window,前进的规则是:对于右指针,每次前进会将hash中的count–,如果出现了count < 0, 说明出现了不应该出现的字符,这时候右指针停止前进。左指针此时出发,开始消掉seen characters,也就是说,每向前滑动,会将count++。我们的目的是将那个count < 0 的fix掉,所以任何一个count被左指针回复为 count == 0,目的就达到了,右指针可以继续前进。
class Solution {
public:
bool checkInclusion(string s1, string s2) {
unordered_map<char, int> hash;
for (char c: s1) hash[c]++;
for (int left = 0, right = 0; right < s2.size(); right++) {
if (--hash[s2[right]] < 0) {
while (++hash[s2[left++]] != 0) {};
}
else if (right - left + 1 == s1.size()) return true;
}
return s1.size() == 0;
}
};
方法3: sliding window (two pointer) + hash + count
class Solution {
public:
bool checkInclusion(string s1, string s2) {
unordered_map<char, int> hash;
for (char c: s1) hash[c]++;
int count = 0;
for (int left = 0, right = 0; right < s2.size(); right++) {
if (--hash[s2[right]] >= 0) {
count ++;
}
else {
while (++hash[s2[left++]] > 0) {
count--;
}
}
if (count == s1.size()) return true;
}
return s1.size() == 0;
}
};