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:

  1. The input strings only contain lower case letters.
  2. 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 };

 

 

posted @ 2018-10-09 21:35  回到明天  阅读(75)  评论(0编辑  收藏  举报