###### tags: `Leetcode` `medium` `sliding window` `python` `c++` # 567. Permutation in String ## [題目連結:] https://leetcode.com/problems/permutation-in-string/description/ ## 題目: Given two strings ```s1``` and ```s2```, return ```true``` if ```s2``` contains a permutation of ```s1```, or ```false``` otherwise. In other words, return ```true``` if one of ```s1```'s permutations is the substring of ```s2```. **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 ``` ## 解題想法: * 此題為給兩個字串,判斷s2中是否包含s1相同結構的連續子字串 * 相同類型[438. Find All Anagrams in a String](/6f6zLrrtTx2xzZr7lJg5SQ) * 使用Silding Window: * 初始: * head=0 * tail=0 * cur=collections.Counter(): 紀錄當前累計的種類數量 * countS1=collections.Counter(s1): 紀錄s1中字符種類數量 * while判斷: * cur[s2[tail]]+=1 * if 長度==len(s1): * if cur==countS1: * return True * 刪s2[head] * head+=1 * tail+=1 * return False ## Python_Sol1: ``` python= #同P438 from collections import Counter class Solution(object): def checkInclusion(self, s1, s2): """ :type s1: str :type s2: str :rtype: bool """ #slide window #best case if len(s1)>len(s2): return False head=0 tail=0 cur=Counter() countS1=Counter(s1) #先存好 while tail<len(s2): cur[s2[tail]]+=1 if tail-head+1==len(s1): if cur==countS1: return True cur[s2[head]]-=1 if cur[s2[head]]==0: #0的話 要刪掉幽靈戶口 del cur[s2[head]] head+=1 tail+=1 return False result=Solution() ans=result.checkInclusion(s1 = "ab", s2 = "eidbaooo") print(ans) ``` ## Python_Sol2: * 因為都是小寫字母,用array存26個位置比較即可 ``` python= class Solution(object): def checkInclusion(self, s1, s2): """ :type s1: str :type s2: str :rtype: bool """ if len(s1)>len(s2): return False l1=[0 for _ in range(26)] l2=[0 for _ in range(26)] for i in range(len(s1)): #ord(a)=97 l1[ord(s1[i])-97]+=1 l2[ord(s2[i])-97]+=1 #first match: if l1==l2: return True #slide window for head in range(len(s2)-len(s1)): #從0~(len(s2)-len(s1)-1) l2[ord(s2[head])-97]-=1 #去頭 l2[ord(s2[head+len(s1)])-97]+=1 #加新尾巴 if l1==l2: return True return False result=Solution() ans=result.checkInclusion(s1 = "ab", s2 = "eidbaooo") print(ans) ``` ## C++_Sol1: ``` cpp= #include<bits/stdc++.h> using namespace std; class Solution { public: bool checkInclusion(string s1, string s2) { int n1=s1.size(), n2=s2.size(); if (n1>n2) return false; int head=0, tail=0; unordered_map<int, int> dic1, cur; for (char item: s1){ dic1[item]+=1; } while (tail<n2){ cur[s2[tail]]+=1; if ((tail-head+1)==n1){ if (dic1==cur) return true; cur[s2[head]]-=1; if (cur[s2[head]]==0) cur.erase(s2[head]); head+=1; } tail+=1; } return false; } }; ``` ## C++_Sol2: ``` cpp= class Solution { public: bool checkInclusion(string s1, string s2) { int n1=s1.size(), n2=s2.size(); if (n1>n2) return false; vector<int> l1(26,0); vector<int> l2(26,0); for (int i=0; i<n1; i++){ l1[int(s1[i])-int('a')]+=1; l2[int(s2[i])-int('a')]+=1; } if (l1==l2) return true; for (int head=0; head<n2-n1; head++){ l2[int(s2[head])-int('a')]-=1; l2[int(s2[head+n1])-int('a')]+=1; if (l1==l2) return true; } return false; } }; ```