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].
Naive解法:从S2左边开始,找到所有可能的长度和S1相同的子字符串,然后sort该子字符串,如果和S1的sort后的字符串一样,就返回true。
1 class Solution { 2 public: 3 bool checkInclusion(string s1, string s2) { 4 if(s2.size()<s1.size()){ 5 return false; 6 } 7 string target = s1; 8 sort(target.begin(),target.end()); 9 const int SIZE = s1.size(); 10 for(int i=0;i<s2.size()-SIZE+1;i++){ 11 string tmp = s2.substr(i,SIZE); 12 sort(tmp.begin(),tmp.end()); 13 if(tmp==target){ 14 return true; 15 } 16 } 17 return false; 18 } 19 };
效率太低,时间复杂度是O(N*M*log(M)),没有合理利用已经计算过的信息:e.g., 前后两个连续的子字符串,s_i,....s_j 和s_(i+1),....s_(j+1),第二个相比第一个多了s_(j+1)而少了s_i,中间的信息重复计算了。
解法二:
1 class Solution { 2 public: 3 bool checkInclusion(string s1, string s2) { 4 vector<int> freq(26,0); 5 int count = 0; 6 for(char c: s1){ 7 if(freq[c-'a']==0){ 8 count++; 9 } 10 freq[c-'a']++; 11 } 12 13 for(int i=0;i<s1.size();i++){ 14 if(freq[s2[i]-'a']==0){ 15 count++; 16 } 17 freq[s2[i]-'a']--; 18 if(freq[s2[i]-'a']==0){ 19 count--; 20 } 21 } 22 23 if(count==0) return true; 24 25 for(int i=s1.size();i<s2.size();i++){ 26 if(freq[s2[i]-'a']==0){ 27 count++; 28 } 29 freq[s2[i]-'a']--; 30 if(freq[s2[i]-'a']==0){ 31 count--; 32 } 33 34 if(freq[s2[i-s1.size()]-'a']==0){ 35 count++; 36 } 37 freq[s2[i-s1.size()]-'a']++; 38 if(freq[s2[i-s1.size()]-'a']==0){ 39 count--; 40 } 41 42 if(count==0) return true; 43 } 44 return false; 45 } 46 };
grandyang 解法一:两个字符串分别用两个hash table来记录,直接比较hash table。
1 class Solution { 2 public: 3 bool checkInclusion(string s1, string s2) { 4 int n1=s1.size(),n2=s2.size(); 5 vector<int> m1(128),m2(128); 6 for(int i=0;i<n1;i++){ 7 m1[s1[i]]++; 8 m2[s2[i]]++; 9 } 10 if(m1==m2) return true; 11 for(int i=n1;i<n2;i++){ 12 m2[s2[i]]++; 13 m2[s2[i-n1]]--; 14 if(m1==m2) return true; 15 } 16 17 return false; 18 } 19 };
另一解法:
1 class Solution { 2 public: 3 bool checkInclusion(string s1, string s2) { 4 if(s1.size()>s2.size()){ 5 return false; 6 } 7 unordered_map<char,int> freq; 8 for(char c: s1){ 9 freq[c]++; 10 } 11 for(int i=0;i<s2.size();i++){ 12 freq[s2[i]]--; 13 if(i>=s1.size()){ 14 freq[s2[i-s1.size()]]++; 15 if(freq[s2[i-s1.size()]]==0){ 16 freq.erase(s2[i-s1.size()]); 17 } 18 } 19 if(freq[s2[i]]==0){ 20 freq.erase(s2[i]); 21 } 22 23 if(freq.size()==0){ 24 return true; 25 } 26 } 27 28 return false; 29 } 30 };