3. 无重复字符的最长子串
此题已刷,链接:点击直达
567. 字符串的排列
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。换句话说,s1 的排列之一是 s2 的 子串 。
具体题目链接
Python
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
s1_length,s2_length=len(s1),len(s2)
if s1_length>s2_length:
return False
s1_dict,s2_dict={},{}
for i in range(s1_length):#初始化字典,使字典将前s1_length个字符统计到字典中。
s1_dict[s1[i]]=s1_dict[s1[i]]+1 if s1[i] in s1_dict else 1
s2_dict[s2[i]]=s2_dict[s2[i]]+1 if s2[i] in s2_dict else 1
if s1_dict==s2_dict: return True#进行第一次比对。
left,right=0,s1_length-1#初始化指针
while right<s2_length-1:
right+=1
s2_dict[s2[right]]=s2_dict[s2[right]]+1 if s2[right] in s2_dict else 1
s2_dict[s2[left]]-=1
if s2_dict[s2[left]]:#如果等于0,则代表字符消失,则删除键值对。
s2_dict.pop(s2[left])
left+=1
if s1_dict==s2_dict: return True
return False
思路:由于排列不会改变字符串中每个字符的个数,所以只有当两个字符串每个字符的个数均相等时,一个字符串才是另一个字符串的排列。因此我才用字典记录字符出现的次数,用s1_dict将s1出现的字符和个数形成键值对,而s2则是进行以s1的长度的子串来建立字典,并在每次指针移动时判断两个字典是否相同,相同则证明排列存在。
GO
func checkInclusion(s1 string, s2 string) bool {
s1_length,s2_length:=len(s1),len(s2)
if s1_length>s2_length{
return false
}
s1_dict,s2_dict:=make(map[byte]int),make(map[byte]int)
for i:=0;i<s1_length;i++{
if _,ok := s1_dict[s1[i]];ok{
s1_dict[s1[i]]++
}else{
s1_dict[s1[i]]=1
}
if _, ok := s2_dict[s2[i]];ok{
s2_dict[s2[i]]++
}else{
s2_dict[s2[i]]=1
}
}
if issame(s1_dict,s2_dict){
return true
}
left,right:=0,s1_length-1
for right<s2_length-1{
right++
if _, ok := s2_dict[s2[right]];ok{
s2_dict[s2[right]]++
}else{
s2_dict[s2[right]]=1
}
s2_dict[s2[left]]--
if s2_dict[s2[left]]==0{
delete(s2_dict,s2[left])
}
left++
if issame(s1_dict,s2_dict){
return true
}
}
return false
}
func issame(m,n map[byte]int) bool{
for key:=range m{
if value, ok := n[key]; !ok || value!=m[key]{
return false
}
}
return true
}
思路:同python,但官网有更简单的方式。