Foundations
Strings
Fundamentals ยท Starter
Complexity
| Operation | Time | Note |
|---|---|---|
s[i], s.at(i), s.charAt(i) | O(1) | |
s.length | O(1) | |
s + t, s.concat(t) | O(n) | Creates a new string |
s.slice(a, b), s.substring(a, b) | O(n) | Copy of the range |
s.indexOf(t), s.includes(t) | O(n ร m) worst | n text, m pattern |
s.split(''), [...s] | O(n) | |
a === b | O(n) | Compares characters |
A string is a sequence of characters. In JavaScript it is immutable: you never change a string, you build a new one. That single fact explains most performance questions about strings.
Building strings
Appending in a loop with += is fine for small inputs, but for large ones collect pieces in an array and join once.
const parts = [];
for (const word of words) parts.push(word.toUpperCase());
const result = parts.join(' ');Characters as numbers
'a'.charCodeAt(0) is 97. Subtracting it maps letters to 0 to 25, which lets you count letters in a fixed array of 26 instead of a Map.
const counts = Array(26).fill(0);
for (const ch of word) counts[ch.charCodeAt(0) - 97]++;JavaScript specifics
- Strings are UTF-16.
'๐'.lengthis 2. Use[...s]orfor...ofto walk by code point. sliceaccepts negative indexes,substringdoes not.localeComparefor locale-aware ordering. The default<compares code units.s.split(' ')on text with repeated spaces produces empty strings.- Strings compare by value (
'a' === 'a'), unlike objects.
Techniques
- Two pointers from both ends: palindromes, reversing.
- Sliding window: longest substring with a property.
- Frequency count: anagrams, permutations in a string.
- Hash map or set: duplicates, first unique character.
- Stack: matching brackets, decoding nested patterns.
- String matching (KMP, Rabin-Karp, Z) for pattern search, in the advanced section.
Common mistakes
- Comparing with
==or forgetting strings are immutable (s[0] = 'x'silently does nothing). - Using
+=in a hot loop over a huge input. - Forgetting case or whitespace rules in the problem statement.
Code
export const isPalindrome = s => {
const t = s.toLowerCase().replace(/[^a-z0-9]/g, '');
for (let l = 0, r = t.length - 1; l < r; l++, r--) if (t[l] !== t[r]) return false;
return true;
}; // O(n) time
export const isAnagram = (a, b) => {
if (a.length !== b.length) return false;
const counts = Array(26).fill(0);
for (let i = 0; i < a.length; i++) {
counts[a.charCodeAt(i) - 97]++;
counts[b.charCodeAt(i) - 97]--;
}
return counts.every(c => c === 0);
}; // O(n) time, O(1) space
export const reverseWords = s => s.trim().split(/\s+/).reverse().join(' ');
export const firstUniqueChar = s => {
const freq = new Map();
for (const ch of s) freq.set(ch, (freq.get(ch) ?? 0) + 1);
return [...s].findIndex(ch => freq.get(ch) === 1);
};
export const compress = s => { // "aaabb" -> "a3b2"
const out = [];
for (let i = 0, j = 0; i < s.length; i = j) {
while (j < s.length && s[j] === s[i]) j++;
out.push(s[i], j - i);
}
return out.join('');
};Practice
Two Pointers
- Valid PalindromeEasy
- Two Sum II - Input Array Is SortedEasy
- Remove Duplicates from Sorted ArrayEasy
- Move ZeroesEasy
- Squares of a Sorted ArrayEasy
- Reverse StringEasy
- Merge Sorted ArrayEasy
- Remove ElementEasy
- 3SumMedium
- 3Sum ClosestMedium
- Container With Most WaterMedium
- Sort ColorsMedium
- Remove Duplicates from Sorted Array IIMedium
- Valid Palindrome IIMedium
- Boats to Save PeopleMedium
- Partition LabelsMedium
- 4SumMedium
- 3Sum SmallerMedium
- Trapping Rain WaterHard
Sliding Window
- Best Time to Buy and Sell StockEasy
- Maximum Average Subarray IEasy
- Contains Duplicate IIEasy
- Longest Nice SubarrayEasy
- Longest Substring Without Repeating CharactersMedium
- Longest Repeating Character ReplacementMedium
- Permutation in StringMedium
- Find All Anagrams in a StringMedium
- Minimum Size Subarray SumMedium
- Max Consecutive Ones IIIMedium
- Fruit Into BasketsMedium
- Longest Substring with At Most K Distinct CharactersMedium
- Subarray Product Less Than KMedium
- Maximum Points You Can Obtain from CardsMedium
- Count Number of Nice SubarraysMedium
- Minimum Window SubstringHard
- Sliding Window MaximumHard
- Substring with Concatenation of All WordsHard
String Matching
- Find the Index of the First Occurrence in a StringEasy
- Repeated Substring PatternEasy
- Is SubsequenceEasy
- Rotate StringEasy
- Longest Palindromic SubstringMedium
- Palindromic SubstringsMedium
- Repeated String MatchMedium
- One Edit DistanceMedium
- Shortest PalindromeHard
- Longest Happy PrefixHard
- Longest Duplicate SubstringHard
- Edit DistanceHard
- Wildcard MatchingHard
Spotted a mistake or something unclear? Report it on GitHub.