1. Problems 1–10
Click a problem to expand it. Each one has a one-line prompt, a short note on the approach, and two fully commented solutions side by side — JavaScript on the left, Python on the right.
P01
Reverse a String
Turn "hello" into "olleh" without a built-in reverse shortcut.
Reverse a String
Turn "hello" into "olleh" without a built-in reverse shortcut.
Approach: walk the string backwards from its last index to its first, appending each character to a new result string as you go.
JavaScript
// Reverse a string without using the built-in Array.reverse() shortcut,
// so the logic itself is visible.
function reverseString(str) {
let reversed = ""; // build the result up one character at a time
for (let i = str.length - 1; i >= 0; i--) {
reversed += str[i]; // walk backwards from the last character
}
return reversed;
}
console.log(reverseString("hello")); // "olleh"
Python
def reverse_string(s: str) -> str:
"""Reverse a string by walking it backwards, one character at a time."""
reversed_str = ""
# range(len(s) - 1, -1, -1) walks the index backwards, like the JS loop
for i in range(len(s) - 1, -1, -1):
reversed_str += s[i]
return reversed_str
# Idiomatic one-liner for real code: s[::-1]
print(reverse_string("hello")) # "olleh"
P02
Check if a String Is a Palindrome
"Was it a car or a cat I saw?" reads the same ignoring case and punctuation.
Check if a String Is a Palindrome
"Was it a car or a cat I saw?" reads the same ignoring case and punctuation.
Approach: strip everything but letters/digits and lowercase it, then use two pointers — one from each end — moving inward and comparing as they go.
JavaScript
// A palindrome reads the same forwards and backwards, e.g. "level".
function isPalindrome(str) {
const cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, ""); // ignore case/punctuation
let left = 0;
let right = cleaned.length - 1;
while (left < right) {
if (cleaned[left] !== cleaned[right]) return false; // mismatch found
left++;
right--;
}
return true; // pointers met without a mismatch
}
console.log(isPalindrome("Was it a car or a cat, I saw?")); // true
Python
import re
def is_palindrome(s: str) -> bool:
"""Two pointers move inward from both ends and compare characters."""
cleaned = re.sub(r"[^a-z0-9]", "", s.lower()) # ignore case/punctuation
left, right = 0, len(cleaned) - 1
while left < right:
if cleaned[left] != cleaned[right]:
return False # mismatch found
left += 1
right -= 1
return True # pointers met without a mismatch
print(is_palindrome("Was it a car or a cat, I saw?")) # True
P03
Count Vowels and Consonants
Classify every letter in a sentence into one of two buckets.
Count Vowels and Consonants
Classify every letter in a sentence into one of two buckets.
Approach: loop over each character, skip anything that isn't a letter, then check membership in a small vowel set to decide which counter to increment.
JavaScript
function countVowelsConsonants(str) {
const vowels = "aeiouAEIOU";
let vowelCount = 0;
let consonantCount = 0;
for (const ch of str) {
if (!/[a-zA-Z]/.test(ch)) continue; // skip spaces, digits, punctuation
if (vowels.includes(ch)) {
vowelCount++;
} else {
consonantCount++;
}
}
return { vowels: vowelCount, consonants: consonantCount };
}
console.log(countVowelsConsonants("Hello World")); // { vowels: 3, consonants: 7 }
Python
def count_vowels_consonants(s: str) -> dict:
vowels = set("aeiouAEIOU")
vowel_count = 0
consonant_count = 0
for ch in s:
if not ch.isalpha(): # skip spaces, digits, punctuation
continue
if ch in vowels:
vowel_count += 1
else:
consonant_count += 1
return {"vowels": vowel_count, "consonants": consonant_count}
print(count_vowels_consonants("Hello World")) # {'vowels': 3, 'consonants': 7}
P04
Character Frequency Count
Build a map of how many times each character appears in a string.
Character Frequency Count
Build a map of how many times each character appears in a string.
Approach: a frequency map is a plain object/dict — for each character, look up its current count (defaulting to 0) and add one.
JavaScript
function charFrequency(str) {
const freq = {};
for (const ch of str) {
freq[ch] = (freq[ch] || 0) + 1; // default to 0 the first time we see ch
}
return freq;
}
console.log(charFrequency("banana"));
// { b: 1, a: 3, n: 2 }
Python
def char_frequency(s: str) -> dict:
freq = {}
for ch in s:
freq[ch] = freq.get(ch, 0) + 1 # default to 0 the first time we see ch
return freq
print(char_frequency("banana"))
# {'b': 1, 'a': 3, 'n': 2}
P05
Check if Two Strings Are Anagrams
"listen" and "silent" use exactly the same letters.
Check if Two Strings Are Anagrams
"listen" and "silent" use exactly the same letters.
Approach: normalize both strings the same way — lowercase, strip non-letters, sort the characters — and compare the results. Two anagrams normalize to an identical string.
JavaScript
function areAnagrams(a, b) {
const normalize = (s) =>
s.toLowerCase().replace(/[^a-z0-9]/g, "").split("").sort().join("");
return normalize(a) === normalize(b); // same letters, same counts, any order
}
console.log(areAnagrams("listen", "silent")); // true
Python
def are_anagrams(a: str, b: str) -> bool:
def normalize(s: str) -> str:
letters = [ch for ch in s.lower() if ch.isalnum()]
return "".join(sorted(letters)) # same letters, same counts, any order
return normalize(a) == normalize(b)
print(are_anagrams("listen", "silent")) # True
P06
First Non-Repeating Character
In "swiss", the first letter that appears only once is "w".
First Non-Repeating Character
In "swiss", the first letter that appears only once is "w".
Approach: two passes over the string. First, build a frequency map of every character. Second, walk the string in order and return the first character whose count is exactly 1.
JavaScript
function firstNonRepeatingChar(str) {
const freq = {};
for (const ch of str) freq[ch] = (freq[ch] || 0) + 1;
for (const ch of str) {
if (freq[ch] === 1) return ch; // first character whose count is exactly 1
}
return null; // every character repeats
}
console.log(firstNonRepeatingChar("swiss")); // "w"
Python
def first_non_repeating_char(s: str) -> str | None:
freq = {}
for ch in s:
freq[ch] = freq.get(ch, 0) + 1
for ch in s:
if freq[ch] == 1: # first character whose count is exactly 1
return ch
return None # every character repeats
print(first_non_repeating_char("swiss")) # "w"
P07
Remove All Whitespace
Strip every space, tab and newline out of a string.
Remove All Whitespace
Strip every space, tab and newline out of a string.
Approach: build a new string by copying over every character that is not a space, tab or newline.
JavaScript
function removeWhitespace(str) {
let result = "";
for (const ch of str) {
if (ch !== " " && ch !== "\t" && ch !== "\n") {
result += ch; // keep everything that isn't a space/tab/newline
}
}
return result;
}
console.log(removeWhitespace(" Hello World ")); // "HelloWorld"
Python
def remove_whitespace(s: str) -> str:
result = ""
for ch in s:
if ch not in (" ", "\t", "\n"): # keep everything that isn't whitespace
result += ch
return result
print(remove_whitespace(" Hello World ")) # "HelloWorld"
P08
Title Case a Sentence
"the quick brown fox" becomes "The Quick Brown Fox".
Title Case a Sentence
"the quick brown fox" becomes "The Quick Brown Fox".
Approach: split the sentence into words, uppercase each word's first letter and lowercase the rest, then join the words back together with spaces.
JavaScript
function toTitleCase(sentence) {
const words = sentence.split(" ");
const capitalized = words.map((word) => {
if (word.length === 0) return word; // guard against double spaces
return word[0].toUpperCase() + word.slice(1).toLowerCase();
});
return capitalized.join(" ");
}
console.log(toTitleCase("the quick brown fox")); // "The Quick Brown Fox"
Python
def to_title_case(sentence: str) -> str:
words = sentence.split(" ")
capitalized = []
for word in words:
if len(word) == 0: # guard against double spaces
capitalized.append(word)
else:
capitalized.append(word[0].upper() + word[1:].lower())
return " ".join(capitalized)
print(to_title_case("the quick brown fox")) # "The Quick Brown Fox"
P09
Check if a String Is All Digits
"48213" qualifies; "482a3" doesn't.
Check if a String Is All Digits
"48213" qualifies; "482a3" doesn't.
Approach: an empty string has no digits, so guard against that first. Otherwise, check every character falls between "0" and "9" — strings compare character-by-character, so this works without converting to a number.
JavaScript
function isAllDigits(str) {
if (str.length === 0) return false; // empty string has no digits
for (const ch of str) {
if (ch < "0" || ch > "9") return false; // any non-digit disqualifies it
}
return true;
}
console.log(isAllDigits("48213")); // true
console.log(isAllDigits("482a3")); // false
Python
def is_all_digits(s: str) -> bool:
if len(s) == 0: # empty string has no digits
return False
for ch in s:
if ch < "0" or ch > "9": # any non-digit disqualifies it
return False
return True
# Idiomatic one-liner for real code: s.isdigit()
print(is_all_digits("48213")) # True
print(is_all_digits("482a3")) # False
P10
Find the Longest Word in a Sentence
In "The crow flew over the mountain", that's "mountain".
Find the Longest Word in a Sentence
In "The crow flew over the mountain", that's "mountain".
Approach: split on spaces, then keep a running "longest so far" — every time a word beats the current record, it becomes the new record.
JavaScript
function longestWord(sentence) {
const words = sentence.split(" ");
let longest = "";
for (const word of words) {
if (word.length > longest.length) {
longest = word; // new record holder
}
}
return longest;
}
console.log(longestWord("The crow flew over the mountain")); // "mountain"
Python
def longest_word(sentence: str) -> str:
words = sentence.split(" ")
longest = ""
for word in words:
if len(word) > len(longest): # new record holder
longest = word
return longest
print(longest_word("The crow flew over the mountain")) # "mountain"
2. Key Takeaways
- Most string problems reduce to one of three moves: a single forward pass, a two-pointer walk from both ends inward, or a frequency map keyed by character.
- JavaScript and Python read almost identically once you know the small vocabulary swap:
str.length↔len(s),freq[ch] || 0↔freq.get(ch, 0), template strings ↔ f-strings. - Both languages ship faster built-ins for several of these (
split("").reverse().join(""),s[::-1],s.isdigit()) — worth knowing, but writing the loop yourself first is what builds the underlying skill.