567. Permutation in String
class Solution {
public boolean checkInclusion(String s1, String s2) {
Map<Character, Integer> map = new HashMap<>();
for (char c : s1.toCharArray()) {
map.put(c, map.getOrDefault(c, 0)+1);
}
int activeCount = 0;
int left = 0;
for (int right = 0; right < s2.length(); right++) {
char rightChar = s2.charAt(right);
if (map.containsKey(rightChar)) {
map.put(rightChar, map.getOrDefault(rightChar, 0)-1);
if (map.get(rightChar) == 0) {
activeCount++;
}
}
while (right - left + 1 > s1.length()) {
char leftChar = s2.charAt(left);
if (map.containsKey(leftChar)) {
if (map.get(leftChar) == 0) { // do this first! left is like a reversed operation
activeCount--;
}
map.put(leftChar, map.getOrDefault(leftChar, 0)+1);
}
left++;
}
// when it leaves while loop, it must right - left + 1 == s1.length()
if (activeCount == map.size()) {
return true;
}
}
return false;
}
}
/**
T: O(n)
S: O(n)
sliding win to find there is a win contains all chars in s1
win size == s1 size -> it's working
use a map to save s1 char, count
then run sliding win to check if cur char in this s1Map
if not in s1Map, move left; -> this is wrong (when left - right + 1 > s1.length()), we shrimp the left
or keeps move right until we find the ans
r
eidbaooo
l
ab
ac = 2
r
eidbaooo
l
ab
ex:
when
s1 = adc
s2 = dcda
notice to comapare this first (because 0 is the 100% accrated,
if we minus map count first then compare != 0 later-> it might original count is not 0!!)
=> if (map.get(leftChar) == 0) {
while (right - left + 1 > s1.length()) {
char leftChar = s2.charAt(left);
if (map.containsKey(leftChar)) {
if (map.get(leftChar) == 0) {
activeCount--;
}
map.put(leftChar, map.getOrDefault(leftChar, 0)+1);
}
left++;
}
*/
T: o(n)
S: o(n)
class Solution {
public boolean checkInclusion(String s1, String s2) {
Map<Character, Integer> needs = new HashMap<>();
for (char c : s1.toCharArray()) {
needs.put(c, needs.getOrDefault(c, 0)+1);
}
int left = 0;
int right = 0;
int matched = 0;
while (right < s2.length()) {
char rightChar = s2.charAt(right);
right++;
if (needs.containsKey(rightChar)) {
needs.put(rightChar, needs.getOrDefault(rightChar, 0)-1);
if (needs.get(rightChar) == 0) {
matched++;
}
}
while (matched == needs.size()) {
if (right - left == s1.length()) { // when len match to s1 -> true
return true;
}
char leftChar = s2.charAt(left);
left++;
if (needs.containsKey(leftChar)) {
if (needs.get(leftChar) == 0) {
matched--;
}
needs.put(leftChar, needs.getOrDefault(leftChar, 0)+1);
}
}
}
return false;
}
}
/*
s1 = "ab" or "ba"
so we can use sliding win to find in s2
this window size must equals to s1, because we only allow s1's permutation
still need a map for s1 (char, count) buid needs map
when current in needs, needs[current]--, if needs[current] == 0 -> matched++
"eidbaooo"
l
r -> when we have entire s1 and (r - l) length != s1 length, shrink left pointer
l
r -> when valid == needs.size() => return true
others return false
shrink left, do needs[left]++, if remove left (need[left] is 0), matched-- (not zero anymore)
*/
Last updated