2953. Count Complete Substrings
Problem Description
You are given a string word
and an integer k
.
A substring is considered complete if it satisfies two conditions:
-
Equal frequency condition: Every character that appears in the substring must occur exactly
k
times. -
Adjacent character condition: For any two adjacent characters in the substring, their positions in the alphabet must differ by at most 2. In other words, if you have two adjacent characters
c1
andc2
, then|ord(c1) - ord(c2)| ≤ 2
.
Your task is to count how many complete substrings exist in the given string word
.
For example, if we have adjacent characters 'a' and 'c', their difference is |97 - 99| = 2
, which satisfies the condition. However, 'a' and 'd' would have a difference of |97 - 100| = 3
, which violates the condition.
The solution approach involves:
- First splitting the string into segments where all adjacent characters satisfy the alphabet distance condition (differ by at most 2)
- For each segment, using a sliding window technique to find all substrings where each character appears exactly
k
times - The window size is determined by the number of unique characters (
i
) multiplied byk
, since each of thei
characters must appear exactlyk
times - Using frequency counters to efficiently track when a window contains exactly
i
characters, each appearing exactlyk
times
Intuition
The key insight is recognizing that the two conditions create natural boundaries in our string. The second condition (adjacent characters must differ by at most 2) acts as a "breaking point" - whenever we encounter two adjacent characters that differ by more than 2, we know that no complete substring can span across this boundary.
This observation leads us to split the original string into segments where all adjacent characters satisfy the alphabet distance constraint. For example, if we have "abcfgh", we'd split it at 'c' and 'f' since |ord('c') - ord('f')| = 3 > 2
.
Once we have these segments, we need to find all substrings within each segment where every character appears exactly k
times. But how do we efficiently check this?
Here's where the mathematical insight comes in: if a substring has i
unique characters and each must appear exactly k
times, then the substring must have exactly i × k
characters. This gives us fixed-size windows to check!
For instance, if k = 2
:
- A substring with 1 unique character must have length 2 (like "aa")
- A substring with 2 unique characters must have length 4 (like "aabb")
- A substring with 3 unique characters must have length 6 (like "aabbcc")
Since we're dealing with lowercase English letters, we have at most 26 unique characters, so we only need to check window sizes from k
to 26k
.
The sliding window technique becomes natural here - for each possible window size l = i × k
, we slide a window of that size across the segment. We maintain:
cnt
: frequency of each character in the current windowfreq
: frequency of frequencies (how many characters appear exactlyj
times)
When freq[k] == i
, it means we have exactly i
characters, each appearing exactly k
times - a complete substring!
This approach elegantly combines the problem's constraints with fixed-size sliding windows, making it efficient to count all complete substrings.
Learn more about Sliding Window patterns.
Solution Approach
The implementation consists of two main parts: splitting the string into valid segments and counting complete substrings within each segment.
Step 1: Splitting the String into Valid Segments
We use two pointers i
and j
to identify segments where all adjacent characters differ by at most 2:
while i < n:
j = i + 1
while j < n and abs(ord(word[j]) - ord(word[j - 1])) <= 2:
j += 1
ans += f(word[i:j])
i = j
Starting from position i
, we extend j
as long as the adjacent character condition is satisfied. Once we find a breaking point, we process the segment word[i:j]
and move to the next segment.
Step 2: Counting Complete Substrings in Each Segment
The helper function f(s)
counts complete substrings within a segment s
. For each possible number of unique characters i
(from 1 to 26):
-
Calculate window size:
l = i * k
(since we needi
characters, each appearingk
times) -
Initialize the first window: Create a frequency counter
cnt
for the firstl
characters, and a frequency-of-frequencies counterfreq
that tracks how many characters appear exactlyj
times. -
Check initial window: If
freq[k] == i
, we have found a complete substring (alli
characters appear exactlyk
times). -
Slide the window: For each new position
j
froml
tom-1
:-
Add new character
s[j]
:freq[cnt[s[j]]] -= 1 # Remove old frequency count cnt[s[j]] += 1 # Increment character count freq[cnt[s[j]]] += 1 # Add new frequency count
-
Remove old character
s[j-l]
:freq[cnt[s[j-l]]] -= 1 # Remove old frequency count cnt[s[j-l]] -= 1 # Decrement character count freq[cnt[s[j-l]]] += 1 # Add new frequency count
-
Check condition: If
freq[k] == i
, increment the answer.
-
Key Data Structures:
cnt
: ACounter
that maintains character frequencies in the current windowfreq
: ACounter
that maintains how many characters have each frequency value
Why This Works:
The freq
counter is the key optimization. Instead of checking if all characters in the window appear exactly k
times (which would require iterating through cnt
), we maintain a count of frequencies. When freq[k] == i
, it means exactly i
characters have frequency k
, and since our window has size i * k
, these must be the only characters in the window.
Time Complexity:
- For each segment, we iterate through at most 26 different window sizes
- For each window size, we slide through the segment once
- Overall:
O(26 * n) = O(n)
wheren
is the length of the string
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example with word = "ababcd"
and k = 2
.
Step 1: Split into valid segments
We check adjacent characters:
- 'a' and 'b':
|97 - 98| = 1 ≤ 2
✓ - 'b' and 'a':
|98 - 97| = 1 ≤ 2
✓ - 'a' and 'b':
|97 - 98| = 1 ≤ 2
✓ - 'b' and 'c':
|98 - 99| = 1 ≤ 2
✓ - 'c' and 'd':
|99 - 100| = 1 ≤ 2
✓
All adjacent characters satisfy the condition, so we have one segment: "ababcd"
.
Step 2: Count complete substrings in segment "ababcd"
We check different window sizes based on the number of unique characters:
For i = 1 (window size = 1 × 2 = 2):
- Window
"ab"
: cnt = {'a':1, 'b':1}, freq = {1:2}, freq[2] = 0 ≠ 1 ✗ - Window
"ba"
: cnt = {'b':1, 'a':1}, freq = {1:2}, freq[2] = 0 ≠ 1 ✗ - Window
"ab"
: cnt = {'a':1, 'b':1}, freq = {1:2}, freq[2] = 0 ≠ 1 ✗ - Window
"bc"
: cnt = {'b':1, 'c':1}, freq = {1:2}, freq[2] = 0 ≠ 1 ✗ - Window
"cd"
: cnt = {'c':1, 'd':1}, freq = {1:2}, freq[2] = 0 ≠ 1 ✗
No complete substrings of size 2.
For i = 2 (window size = 2 × 2 = 4):
- Window
"abab"
: cnt = {'a':2, 'b':2}, freq = {2:2}, freq[2] = 2 ✓ (Found one!) - Window
"babc"
: cnt = {'b':2, 'a':1, 'c':1}, freq = {1:2, 2:1}, freq[2] = 1 ≠ 2 ✗ - Window
"abcd"
: cnt = {'a':1, 'b':1, 'c':1, 'd':1}, freq = {1:4}, freq[2] = 0 ≠ 2 ✗
Found 1 complete substring: "abab"
.
For i = 3 (window size = 3 × 2 = 6):
- Window
"ababcd"
: cnt = {'a':2, 'b':2, 'c':1, 'd':1}, freq = {1:2, 2:2}, freq[2] = 2 ≠ 3 ✗
No complete substrings of size 6.
Total count: 1
The only complete substring is "abab"
where:
- Each character ('a' and 'b') appears exactly k=2 times
- All adjacent characters differ by at most 2 (|'a'-'b'| = 1)
Let's trace through word = "aabaab"
with k = 3
.
Phase 1: Segment identification Check each adjacent pair:
- 'a','a': |97-97| = 0 ≤ 2 ✓
- 'a','b': |97-98| = 1 ≤ 2 ✓
- 'b','a': |98-97| = 1 ≤ 2 ✓
- 'a','a': |97-97| = 0 ≤ 2 ✓
- 'a','b': |97-98| = 1 ≤ 2 ✓
Result: One segment "aabaab"
(length 6)
Phase 2: Window sliding for each possible unique character count
Window size for i=1: 1×3=3
- Position 0-2:
"aab"
→ cnt={'a':2,'b':1}, freq={1:1,2:1}, need freq[3]=1 but have 0 ✗ - Position 1-3:
"aba"
→ cnt={'a':2,'b':1}, freq={1:1,2:1}, freq[3]=0 ✗ - Position 2-4:
"baa"
→ cnt={'b':1,'a':2}, freq={1:1,2:1}, freq[3]=0 ✗ - Position 3-5:
"aab"
→ cnt={'a':2,'b':1}, freq={1:1,2:1}, freq[3]=0 ✗
Window size for i=2: 2×3=6
- Position 0-5:
"aabaab"
→ cnt={'a':4,'b':2}, freq={2:1,4:1}, need freq[3]=2 but have 0 ✗
Result: 0 complete substrings
None of the substrings satisfy both conditions - no character appears exactly 3 times in any valid window.
Solution Implementation
1from collections import Counter
2
3class Solution:
4 def countCompleteSubstrings(self, word: str, k: int) -> int:
5 def count_complete_in_segment(segment: str) -> int:
6 """
7 Count complete substrings in a segment where adjacent chars differ by at most 2.
8 A complete substring has each character appearing exactly k times.
9 """
10 segment_length = len(segment)
11 result = 0
12
13 # Try all possible numbers of unique characters (1 to 26)
14 for num_unique_chars in range(1, 27):
15 # Calculate the required window size
16 window_size = num_unique_chars * k
17
18 # Skip if window size exceeds segment length
19 if window_size > segment_length:
20 break
21
22 # Initialize counters for the first window
23 char_count = Counter(segment[:window_size])
24 frequency_count = Counter(char_count.values())
25
26 # Check if first window is complete (all chars appear exactly k times)
27 result += frequency_count[k] == num_unique_chars
28
29 # Slide the window through the rest of the segment
30 for right in range(window_size, segment_length):
31 # Character entering the window
32 entering_char = segment[right]
33
34 # Update frequency counter before changing char count
35 frequency_count[char_count[entering_char]] -= 1
36 char_count[entering_char] += 1
37 frequency_count[char_count[entering_char]] += 1
38
39 # Character leaving the window
40 leaving_char = segment[right - window_size]
41
42 # Update frequency counter before changing char count
43 frequency_count[char_count[leaving_char]] -= 1
44 char_count[leaving_char] -= 1
45 frequency_count[char_count[leaving_char]] += 1
46
47 # Check if current window is complete
48 result += frequency_count[k] == num_unique_chars
49
50 return result
51
52 # Main function logic
53 total_count = 0
54 string_length = len(word)
55 start_index = 0
56
57 # Split the string into segments where adjacent chars differ by at most 2
58 while start_index < string_length:
59 end_index = start_index + 1
60
61 # Extend segment while adjacent characters differ by at most 2
62 while end_index < string_length and abs(ord(word[end_index]) - ord(word[end_index - 1])) <= 2:
63 end_index += 1
64
65 # Count complete substrings in this segment
66 total_count += count_complete_in_segment(word[start_index:end_index])
67
68 # Move to next segment
69 start_index = end_index
70
71 return total_count
72
1class Solution {
2 /**
3 * Counts the number of complete substrings in the given word.
4 * A complete substring has all characters appearing exactly k times,
5 * and adjacent characters differ by at most 2 in ASCII value.
6 *
7 * @param word the input string
8 * @param k the required frequency for each character
9 * @return the count of complete substrings
10 */
11 public int countCompleteSubstrings(String word, int k) {
12 int n = word.length();
13 int totalCount = 0;
14
15 // Process segments where adjacent characters differ by at most 2
16 for (int startIdx = 0; startIdx < n;) {
17 int endIdx = startIdx + 1;
18
19 // Find the end of current segment where adjacent chars differ by at most 2
20 while (endIdx < n && Math.abs(word.charAt(endIdx) - word.charAt(endIdx - 1)) <= 2) {
21 endIdx++;
22 }
23
24 // Count complete substrings in this segment
25 totalCount += countCompleteInSegment(word.substring(startIdx, endIdx), k);
26 startIdx = endIdx;
27 }
28
29 return totalCount;
30 }
31
32 /**
33 * Counts complete substrings within a segment where each character appears exactly k times.
34 * Uses sliding window technique for each possible number of distinct characters.
35 *
36 * @param segment the string segment to process
37 * @param k the required frequency for each character
38 * @return the count of complete substrings in the segment
39 */
40 private int countCompleteInSegment(String segment, int k) {
41 int segmentLength = segment.length();
42 int completeSubstrCount = 0;
43
44 // Try windows with i distinct characters (1 to 26)
45 for (int distinctChars = 1; distinctChars <= 26 && distinctChars * k <= segmentLength; distinctChars++) {
46 int windowSize = distinctChars * k;
47 int[] charFrequency = new int[26];
48
49 // Initialize the first window
50 for (int j = 0; j < windowSize; j++) {
51 charFrequency[segment.charAt(j) - 'a']++;
52 }
53
54 // Track frequency distribution using a map
55 // Key: frequency value, Value: count of characters with that frequency
56 Map<Integer, Integer> frequencyDistribution = new HashMap<>();
57 for (int freq : charFrequency) {
58 if (freq > 0) {
59 frequencyDistribution.merge(freq, 1, Integer::sum);
60 }
61 }
62
63 // Check if all distinctChars characters have frequency k
64 if (frequencyDistribution.getOrDefault(k, 0) == distinctChars) {
65 completeSubstrCount++;
66 }
67
68 // Slide the window through the rest of the segment
69 for (int rightIdx = windowSize; rightIdx < segmentLength; rightIdx++) {
70 int leftIdx = rightIdx - windowSize;
71 int newCharIndex = segment.charAt(rightIdx) - 'a';
72 int oldCharIndex = segment.charAt(leftIdx) - 'a';
73
74 // Update frequency distribution for the new character
75 frequencyDistribution.merge(charFrequency[newCharIndex], -1, Integer::sum);
76 charFrequency[newCharIndex]++;
77 frequencyDistribution.merge(charFrequency[newCharIndex], 1, Integer::sum);
78
79 // Update frequency distribution for the removed character
80 frequencyDistribution.merge(charFrequency[oldCharIndex], -1, Integer::sum);
81 charFrequency[oldCharIndex]--;
82 frequencyDistribution.merge(charFrequency[oldCharIndex], 1, Integer::sum);
83
84 // Check if current window forms a complete substring
85 if (frequencyDistribution.getOrDefault(k, 0) == distinctChars) {
86 completeSubstrCount++;
87 }
88 }
89 }
90
91 return completeSubstrCount;
92 }
93}
94
1class Solution {
2public:
3 int countCompleteSubstrings(string word, int k) {
4 int n = word.length();
5 int totalCount = 0;
6
7 // Helper function to count complete substrings in a valid segment
8 // A complete substring has each character appearing exactly k times
9 auto countCompleteInSegment = [&](string segment) {
10 int segmentLength = segment.length();
11 int count = 0;
12
13 // Try all possible number of unique characters (1 to 26)
14 for (int uniqueChars = 1; uniqueChars <= 26 && uniqueChars * k <= segmentLength; ++uniqueChars) {
15 int windowSize = uniqueChars * k; // Each of uniqueChars chars appears k times
16 int charFrequency[26]{}; // Frequency of each character in current window
17
18 // Initialize the first window
19 for (int j = 0; j < windowSize; ++j) {
20 ++charFrequency[segment[j] - 'a'];
21 }
22
23 // Count how many characters have each frequency value
24 unordered_map<int, int> frequencyCount;
25 for (int freq : charFrequency) {
26 if (freq > 0) {
27 frequencyCount[freq]++;
28 }
29 }
30
31 // Check if all uniqueChars characters appear exactly k times
32 if (frequencyCount[k] == uniqueChars) {
33 ++count;
34 }
35
36 // Slide the window through the segment
37 for (int j = windowSize; j < segmentLength; ++j) {
38 int addedChar = segment[j] - 'a'; // Character entering the window
39 int removedChar = segment[j - windowSize] - 'a'; // Character leaving the window
40
41 // Update frequency count for the added character
42 frequencyCount[charFrequency[addedChar]]--;
43 charFrequency[addedChar]++;
44 frequencyCount[charFrequency[addedChar]]++;
45
46 // Update frequency count for the removed character
47 frequencyCount[charFrequency[removedChar]]--;
48 charFrequency[removedChar]--;
49 frequencyCount[charFrequency[removedChar]]++;
50
51 // Check if current window forms a complete substring
52 if (frequencyCount[k] == uniqueChars) {
53 ++count;
54 }
55 }
56 }
57 return count;
58 };
59
60 // Split the word into segments where consecutive characters differ by at most 2
61 for (int i = 0; i < n;) {
62 int j = i + 1;
63
64 // Extend segment while consecutive characters satisfy the constraint
65 while (j < n && abs(word[j] - word[j - 1]) <= 2) {
66 ++j;
67 }
68
69 // Count complete substrings in this valid segment
70 totalCount += countCompleteInSegment(word.substr(i, j - i));
71
72 // Move to the next segment
73 i = j;
74 }
75
76 return totalCount;
77 }
78};
79
1/**
2 * Counts the number of complete substrings in a word where:
3 * - Each character appears exactly k times
4 * - Adjacent characters have ASCII difference at most 2
5 * @param word - The input string to analyze
6 * @param k - The required frequency for each character
7 * @returns The count of complete substrings
8 */
9function countCompleteSubstrings(word: string, k: number): number {
10 /**
11 * Helper function to count complete substrings in a segment
12 * where all adjacent characters have ASCII difference at most 2
13 * @param segment - A substring where adjacent chars differ by at most 2
14 * @returns Count of complete substrings in this segment
15 */
16 const countCompleteInSegment = (segment: string): number => {
17 const segmentLength = segment.length;
18 let completeCount = 0;
19
20 // Try all possible numbers of unique characters (1 to 26)
21 for (let uniqueChars = 1; uniqueChars <= 26 && uniqueChars * k <= segmentLength; uniqueChars++) {
22 // Window size for current number of unique characters
23 const windowSize = uniqueChars * k;
24
25 // Character frequency array for current window (26 letters)
26 const charFrequency: number[] = new Array(26).fill(0);
27
28 // Initialize first window
29 for (let i = 0; i < windowSize; i++) {
30 const charIndex = segment.charCodeAt(i) - 'a'.charCodeAt(0);
31 charFrequency[charIndex]++;
32 }
33
34 // Frequency map: maps frequency value to count of characters with that frequency
35 const frequencyMap: { [key: number]: number } = {};
36 for (const freq of charFrequency) {
37 if (freq > 0) {
38 frequencyMap[freq] = (frequencyMap[freq] || 0) + 1;
39 }
40 }
41
42 // Check if first window is complete (all chars appear exactly k times)
43 if (frequencyMap[k] === uniqueChars) {
44 completeCount++;
45 }
46
47 // Slide the window through the segment
48 for (let rightIndex = windowSize; rightIndex < segmentLength; rightIndex++) {
49 // Character entering the window
50 const enteringCharIndex = segment.charCodeAt(rightIndex) - 'a'.charCodeAt(0);
51 // Character leaving the window
52 const leavingCharIndex = segment.charCodeAt(rightIndex - windowSize) - 'a'.charCodeAt(0);
53
54 // Update frequency map for entering character
55 frequencyMap[charFrequency[enteringCharIndex]]--;
56 charFrequency[enteringCharIndex]++;
57 frequencyMap[charFrequency[enteringCharIndex]] = (frequencyMap[charFrequency[enteringCharIndex]] || 0) + 1;
58
59 // Update frequency map for leaving character
60 frequencyMap[charFrequency[leavingCharIndex]]--;
61 charFrequency[leavingCharIndex]--;
62 frequencyMap[charFrequency[leavingCharIndex]] = (frequencyMap[charFrequency[leavingCharIndex]] || 0) + 1;
63
64 // Check if current window is complete
65 if (frequencyMap[k] === uniqueChars) {
66 completeCount++;
67 }
68 }
69 }
70
71 return completeCount;
72 };
73
74 const wordLength = word.length;
75 let totalCompleteSubstrings = 0;
76
77 // Split word into segments where adjacent characters differ by at most 2
78 let segmentStart = 0;
79 while (segmentStart < wordLength) {
80 let segmentEnd = segmentStart + 1;
81
82 // Extend segment while adjacent characters differ by at most 2
83 while (segmentEnd < wordLength &&
84 Math.abs(word.charCodeAt(segmentEnd) - word.charCodeAt(segmentEnd - 1)) <= 2) {
85 segmentEnd++;
86 }
87
88 // Process current segment and add complete substrings count
89 const currentSegment = word.substring(segmentStart, segmentEnd);
90 totalCompleteSubstrings += countCompleteInSegment(currentSegment);
91
92 // Move to next segment
93 segmentStart = segmentEnd;
94 }
95
96 return totalCompleteSubstrings;
97}
98
Time and Space Complexity
Time Complexity: O(n × |Σ|)
where n
is the length of the string word
and |Σ| = 26
represents the size of the character set (lowercase English letters).
The analysis breaks down as follows:
- The outer while loop in the main function iterates through the string
word
once, partitioning it into segments where consecutive characters differ by at most 2. This takesO(n)
time total. - For each segment, the function
f(s)
is called, which:- Iterates through at most 26 possible values of
i
(representing 1 to 26 unique characters) - For each
i
, it uses a sliding window of sizel = i × k
- The sliding window traverses the segment once, performing
O(1)
operations per position (updating counters and frequency maps) - Each segment is processed in
O(m × 26)
wherem
is the segment length
- Iterates through at most 26 possible values of
- Since the sum of all segment lengths equals
n
, the total time across all segments isO(n × 26) = O(n × |Σ|)
Space Complexity: O(|Σ|)
where |Σ| = 26
.
The space usage consists of:
cnt
: A Counter that stores at most 26 different characters (lowercase letters), requiringO(26)
spacefreq
: A Counter that stores frequency counts, with at most 26 different frequency values, requiringO(26)
space- Other variables use
O(1)
space - The recursive calls and string slicing
word[i:j]
create new strings, but at most one segment is processed at a time, and the space for the segment is bounded byO(n)
in the worst case, but the dominant space usage for the algorithm's working memory isO(|Σ|)
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Frequency Counter Updates When Sliding Window
The Pitfall: When sliding the window, developers often update the character count first and then the frequency counter, but forget that the order matters. A common mistake is:
# WRONG: Updates char_count before updating freq counter char_count[entering_char] += 1 frequency_count[char_count[entering_char]] += 1 frequency_count[char_count[entering_char] - 1] -= 1 # Wrong old frequency
Why It's Wrong: After incrementing char_count[entering_char]
, you've lost the original frequency value. Trying to decrement the old frequency becomes error-prone.
The Solution: Always update the frequency counter BEFORE modifying the character counter:
# CORRECT: Update frequency counter first frequency_count[char_count[entering_char]] -= 1 # Remove old frequency char_count[entering_char] += 1 # Update character count frequency_count[char_count[entering_char]] += 1 # Add new frequency
2. Forgetting to Handle Zero Frequencies
The Pitfall: When a character's count becomes 0 (it leaves the window completely), the frequency counter still tracks that there's a character with frequency 0. This can lead to incorrect validation:
# This check might fail even when valid if frequency_count[k] == num_unique_chars: # frequency_count[0] might be > 0
The Solution: The current implementation handles this correctly by maintaining the frequency counter properly. When a character count becomes 0, frequency_count[0]
increases, but this doesn't affect our check since we only care about frequency_count[k]
.
3. Off-by-One Error in Window Sliding
The Pitfall: Incorrectly calculating which character is leaving the window:
# WRONG: Off by one
leaving_char = segment[right - window_size + 1] # Wrong index
# WRONG: Using wrong boundary
for right in range(window_size - 1, segment_length): # Wrong starting point
The Solution: The leaving character should be at index right - window_size
:
# CORRECT
for right in range(window_size, segment_length):
leaving_char = segment[right - window_size] # Correct index
4. Not Breaking Early When Window Size Exceeds Segment
The Pitfall: Continuing to check larger window sizes even when they exceed the segment length, leading to unnecessary iterations:
# INEFFICIENT: No early termination
for num_unique_chars in range(1, 27):
window_size = num_unique_chars * k
# Continues even when window_size > segment_length
The Solution: Break early when the window size becomes too large:
# EFFICIENT: Early termination if window_size > segment_length: break
5. Misunderstanding the Complete Substring Condition
The Pitfall: Checking if AT LEAST num_unique_chars
characters have frequency k
, rather than EXACTLY:
# WRONG: Allows more than num_unique_chars distinct characters if frequency_count[k] >= num_unique_chars: # Wrong condition
Why It's Wrong: If we have a window of size 3k
(expecting 3 unique chars), but 4 different characters appear with some having frequency k
, this would incorrectly count as valid.
The Solution: Use strict equality to ensure EXACTLY the expected number of unique characters:
# CORRECT: Exactly num_unique_chars characters must have frequency k if frequency_count[k] == num_unique_chars:
This works because if the window has size num_unique_chars * k
and exactly num_unique_chars
characters have frequency k
, then these must be the only characters in the window (no room for other characters).
What does the following code do?
1def f(arr1, arr2):
2 i, j = 0, 0
3 new_arr = []
4 while i < len(arr1) and j < len(arr2):
5 if arr1[i] < arr2[j]:
6 new_arr.append(arr1[i])
7 i += 1
8 else:
9 new_arr.append(arr2[j])
10 j += 1
11 new_arr.extend(arr1[i:])
12 new_arr.extend(arr2[j:])
13 return new_arr
14
1public static List<Integer> f(int[] arr1, int[] arr2) {
2 int i = 0, j = 0;
3 List<Integer> newArr = new ArrayList<>();
4
5 while (i < arr1.length && j < arr2.length) {
6 if (arr1[i] < arr2[j]) {
7 newArr.add(arr1[i]);
8 i++;
9 } else {
10 newArr.add(arr2[j]);
11 j++;
12 }
13 }
14
15 while (i < arr1.length) {
16 newArr.add(arr1[i]);
17 i++;
18 }
19
20 while (j < arr2.length) {
21 newArr.add(arr2[j]);
22 j++;
23 }
24
25 return newArr;
26}
27
1function f(arr1, arr2) {
2 let i = 0, j = 0;
3 let newArr = [];
4
5 while (i < arr1.length && j < arr2.length) {
6 if (arr1[i] < arr2[j]) {
7 newArr.push(arr1[i]);
8 i++;
9 } else {
10 newArr.push(arr2[j]);
11 j++;
12 }
13 }
14
15 while (i < arr1.length) {
16 newArr.push(arr1[i]);
17 i++;
18 }
19
20 while (j < arr2.length) {
21 newArr.push(arr2[j]);
22 j++;
23 }
24
25 return newArr;
26}
27
Recommended Readings
https assets algo monster cover_photos stack svg Sliding Window Maximum Monotonic Stack We have an array and a sliding window defined by a start index and an end index The sliding window moves from left of the array to right There are always k elements in the window The window
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!