Permutation in String
MediumThe problem
Given two strings s1 and s2, return true if s2 contains a piece (letters next to each other) that is a rearrangement of s1, using all of its letters exactly once. Otherwise return false.
- Example 1Input: s1 = "abc", s2 = "xxcbaxx"Output: true
The piece "cba" is a rearrangement of "abc".
- Example 2Input: s1 = "abc", s2 = "acxbxxc"Output: false
No piece of length 3 has exactly the letters a, b and c.
- Example 3Input: s1 = "ab", s2 = "a"Output: false
s2 is too short to contain s1's letters.
- 1 ≤ s1.length, s2.length ≤ 100,000
- Both strings contain only lowercase letters a to z
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
A permutation has the same letter counts. What size must the window always be?
The idea
Slide a fixed-size window (length of s1) over s2, maintaining 26 counts; compare with s1 counts (or track how many letters match).
Target: O(n) time, O(1) space
Go function shape
func checkInclusion(s1 string, s2 string) boolReference solution
Tested with go test. Try it yourself first, then compare.
// CheckInclusion: s2 contains a permutation of s1 when some window of len(s1) has the same letter counts.
func CheckInclusion(s1, s2 string) bool {
if len(s1) > len(s2) {
return false
}
var need, have [26]int
for i := 0; i < len(s1); i++ {
need[s1[i]-'a']++
have[s2[i]-'a']++
}
if need == have {
return true
}
for i := len(s1); i < len(s2); i++ {
have[s2[i]-'a']++ // letter enters on the right
have[s2[i-len(s1)]-'a']-- // letter leaves on the left
if need == have {
return true
}
}
return false
}