Use sliding window technique and store all characters in a int[256] map. Outer while loop use to expand window, inner while loop to shrink window. Update every time.
publicintlengthOfLongestSubstring(String s){if(s ==null||s.isEmpty()){return0;}intres=0;int[]map=newint[256];intL=0, R =0;while(R<s.length()){ map[s.charAt(R)]++;while(map[s.charAt(R)]>1){ map[s.charAt(L)]--; L++;} res =Math.max(res, R - L +1); R++;}return res;}
deflengthOfLongestSubstring(self,s:str)->int: dic ={} L =0 res =0for R inrange(len(s)):if s[R]notin dic: dic[s[R]]=0 dic[s[R]]+=1while dic[s[R]]>1: lc = s[L] dic[lc]-=1 L +=1 res =max(res, R - L +1)return res
Use a unique count variable to count how many unique characters are in the window. if map[s.charAt(R)] == 1, increase the count, when map[s.charAt(L)] == 0, decrease the count.
Use sliding window to keep track of the records. HashMap to record char and its count. Preprocess target string with map. Use char count == 0 and length count == t.length() to represent when all records are found
String: ADOBECODEBANC
j i
If (map.contains(nums[i]) reduce count of that char, when count >=0 , foundCount++;
While foundCount == t.length(). Update result. And reduce window size by moving j.
When map.contains(nums[j]), count of char ++, when map.get(char[j]) > 1, foundCount--; and j++;
This problem is hard to interpret. It means you have to select k cards from begin or end or both. This is actually a two pointer + sliding window problem. LSum represents the sum on left side, then slide to the left, RSum is the sum on the right side. LSum + RSum is one of the result.
Get all words into a set of string combinations by using backtracking. Slide window and compare substring. First step took very long since backtracking takes O(k^2) where k is size of words
public int lengthOfLongestSubstringTwoDistinct(String s) {
if (s == null || s.isEmpty()) {
return 0;
}
int res = 0;
int[] map = new int[256];
int L = 0, R = 0, count = 0;
while (R < s.length()) {
map[s.charAt(R)]++;
if (map[s.charAt(R)] == 1) {
count++;
}
while (count > 2) {
map[s.charAt(L)]--;
if (map[s.charAt(L)] == 0) count--;
L++;
}
res = Math.max(res, R - L + 1);
R++;
}
return res;
}
public int lengthOfLongestSubstringKDistinct(String s, int k) {
if (s == null || s.isEmpty()) {
return 0;
}
int res = 0;
int[] map = new int[256];
int L = 0, R = 0, count = 0;
while (R < s.length()) {
map[s.charAt(R)]++;
if (map[s.charAt(R)] == 1) {
count++;
}
while (count > k) {
map[s.charAt(L)]--;
if (map[s.charAt(L)] == 0) count--;
L++;
}
res = Math.max(res, R - L + 1);
R++;
}
return res;
}
public int totalFruit(int[] tree) {
int n = tree.length;
int[] map = new int[n];
int res = 0, count = 0;
for (int L = 0, R = 0; R < n; R++) {
int rc = tree[R];
if (++map[rc] == 1) {
count++;
}
while (count > 2) {
int lc = tree[L++];
if (--map[lc] == 0) {
count--;
}
}
res = Math.max(res, R - L + 1);
}
return res;
}
def totalFruit(self, tree: List[int]) -> int:
dic = {}
L, R, n, count, res = 0, 0, len(tree), 0, 0;
while R < n:
rc = tree[R]
if rc not in dic:
dic[rc] = 0;
dic[rc] += 1
if dic[rc] == 1:
count += 1
while count > 2:
lc = tree[L]
dic[lc] -= 1
if dic[lc] == 0:
count -= 1
L += 1
res = max(res, R - L + 1)
R += 1
return res
public String minWindow(String s, String t) {
int[] map = new int[256];
for (char c : t.toCharArray()) {
map[c]++;
}
int min = Integer.MAX_VALUE, minLeft = 0;
int L = 0, R = 0, count = 0;
while (R < s.length()) {
if (map[s.charAt(R)]-- > 0) {
count++;
}
while (count == t.length()) {
if (R - L + 1 < min) {
min = R - L + 1;
minLeft = L;
}
if (map[s.charAt(L)]++ >= 0) {
count--;
}
L++;
}
R++;
}
return min == Integer.MAX_VALUE ? "" : s.substring(minLeft, minLeft + min);
}
public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<>();
int[] map = new int[256];
for (int c : p.toCharArray()) {
map[c]++;
}
int L = 0, R = 0, count = 0;
while (R < s.length()) {
if (map[s.charAt(R)]-- > 0) {
count++;
}
while (R - L + 1 == p.length()) {
if (count == p.length()) {
result.add(L);
}
if (map[s.charAt(L)]++ >= 0) {
count--;
}
L++;
}
R++;
}
return result;
}
int maxVowels(string s, int k) {
std::string vowels = "aeiou";
int vCount = 0, res = 0;
int left = 0;
for (int right = 0; right < s.size(); ++right) {
char c = s.at(right);
if (vowels.find(c) != std::string::npos) {
vCount++;
}
if (right - left >= k) {
char lc = s.at(left);
if (vowels.find(lc) != std::string::npos) {
--vCount;
}
left++;
}
res = max(res, vCount);
}
return res;
}
public int longestSubstring(String s, int k) {
int max = 0;
for (int i = 1; i <= 26; i++) {
max = Math.max(max, helper(s, k, i));
}
return max;
}
private int helper(String s, int k, int uniqueLimit) {
int[] map = new int[256];
int count = 0;
int numNoLessThanK = 0;
int max = 0;
for (int i = 0, left = 0; i < s.length(); i++) {
if (map[s.charAt(i)]++ == 0) count++;
if (map[s.charAt(i)] == k) numNoLessThanK++;
while (count > uniqueLimit) {
if (map[s.charAt(left)]-- == k) numNoLessThanK--;
if (map[s.charAt(left)] == 0) count--;
left++;
}
if (count == uniqueLimit && count == numNoLessThanK) {
max = Math.max(max, i - left + 1);
}
}
return max;
}
public int subarraysWithKDistinct(int[] A, int K) {
return helper(A, K) - helper(A, K - 1);
}
private int helper(int[] A, int K) {
int n = A.length;
int[] map = new int[n + 1];
int count = 0, res = 0;
for (int i = 0, left = 0; i < n; i++) {
if (++map[A[i]] == 1) {
count++;
}
while (count > K) {
if (--map[A[left++]] == 0) {
count--;
}
}
res += i - left + 1;
}
return res;
}
public int minSubArrayLen(int s, int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int L = 0, R = 0;
long sum = 0;
int res = Integer.MAX_VALUE;
while (R < nums.length) {
sum += nums[R];
while (sum >= s) {
res = Math.min(res, R - L + 1);
sum -= nums[L++];
}
R++;
}
return res == Integer.MAX_VALUE ? 0 : res;
}
public int maxScore(int[] cardPoints, int k) {
int n = cardPoints.length;
int lsum = 0, rsum = 0;
for (int i = 0; i < k; i++) {
lsum += cardPoints[i];
}
int res = lsum + rsum;
for (int i = 0; i < k; i++) {
lsum -= cardPoints[k - i - 1];
rsum += cardPoints[n - i - 1];
res = Math.max(res, lsum + rsum);
}
return res;
}
function characterReplacement(s: string, k: number): number {
const freq: Record<string, number> = {};
let maxCount = 0; // max frequency of a single char in current window
let left = 0;
let maxLength = 0;
for (let right = 0; right < s.length; right++) {
const rightChar = s[right];
freq[rightChar] = (freq[rightChar] || 0) + 1;
maxCount = Math.max(maxCount, freq[rightChar]);
// If more than k chars need to be replaced, shrink window
while ((right - left + 1) - maxCount > k) {
const leftChar = s[left];
freq[leftChar]--;
left++;
// Note: no need to update maxCount here because it only ever grows or stays the same,
// which is fine for correctness in this problem.
}
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
function countSubarrays(nums: number[], k: number): number {
const maxElement = Math.max(...nums);
let left = 0;
let ans = 0;
let maxElementInWindow = 0;
for (let right = 0; right < nums.length; right++) {
if (nums[right] === maxElement) {
maxElementInWindow++;
}
while (maxElementInWindow >= k) {
if (nums[left] === maxElement) {
maxElementInWindow--;
}
left++;
}
ans += left;
}
return ans;
};
class Solution {
public:
int equalCountSubstrings(string s, int count) {
int ans = 0;
int n = s.size();
for (int distinctTarget = 1; distinctTarget <= 26; distinctTarget++) {
vector<int> freq(26, 0);
int left = 0, right = 0;
int unique = 0; // number of unique chars in window
int countAtTarget = 0; // chars whose frequency == count
while (right < n) {
int idx = s[right] - 'a';
freq[idx]++;
if (freq[idx] == 1) unique++;
if (freq[idx] == count) countAtTarget++;
while (unique > distinctTarget || (right - left + 1) > distinctTarget * count) {
int leftIdx = s[left] - 'a';
if (freq[leftIdx] == count) countAtTarget--;
freq[leftIdx]--;
if (freq[leftIdx] == 0) unique--;
left++;
}
if (unique == distinctTarget && countAtTarget == distinctTarget
&& (right - left + 1) == distinctTarget * count) {
ans++;
}
right++;
}
}
return ans;
}
};
class Solution {
public:
int longestEqualSubarray(vector<int>& nums, int k) {
unordered_map<int, vector<int>> countMap;
int left = 0;
int res = 0;
int n = nums.size();
for (int i = 0; i < n; ++i) {
countMap[nums[i]].push_back(i);
}
for (const auto& [val, indicies] : countMap) {
int left = 0;
for (int right = 0; right < indicies.size(); ++right) {
// indicies[right] - indicies[left] - (right - left) <> k
while (indicies[right] - indicies[left] - (right - left) > k) {
++left;
}
res = max(res, right - left + 1);
}
}
return res;
}
};