String Coding Interview Problems - 12 Most Asked Questions With Solutions
After arrays, strings are the second most commonly tested data structure in coding interviews. Almost every technical round - from a startup screening to a FAANG interview - includes at least one string problem. The good news is that string problems follow recognizable patterns. Once you internalize those patterns, most problems become much more approachable than they first appear.
In this guide we cover 12 of the most frequently asked string interview problems with clear explanations, optimal approaches, and working code examples in JavaScript and Java. If you have not already, check out our Array Coding Interview Problems guide - many of the same patterns apply to both.
Key String Concepts to Know Before the Interview
- Strings are immutable in Java and JavaScript - every modification creates a new string
- Use a HashMap / frequency map for character counting problems
- Use two pointers for palindrome and reverse problems
- Use a sliding window for substring problems
- Always clarify - is the string ASCII only, or does it include Unicode?
- Always ask - is the input case-sensitive?
Problem 1 - Reverse a String
Problem: Reverse a given string in place.
Input: "tipsandtricks"
Output: "skcirtdnaspit"
// JavaScript - split, reverse, join
function reverseString(str) {
return str.split("").reverse().join("");
}
// JavaScript - two pointer approach (more interview-friendly)
function reverseString(str) {
const arr = str.split("");
let left = 0, right = arr.length - 1;
while (left < right) {
[arr[left], arr[right]] = [arr[right], arr[left]];
left++;
right--;
}
return arr.join("");
}
reverseString("tipsandtricks"); // "skcirtdnaspit"
// Java
public String reverseString(String s) {
char[] chars = s.toCharArray();
int left = 0, right = chars.length - 1;
while (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
return new String(chars);
}
Interview tip: Always mention the two-pointer approach even if the language has a built-in reverse. It shows you understand the underlying algorithm - which is what interviewers actually want to see.
Problem 2 - Check if a String is a Palindrome
Problem: Given a string, return true if it reads the same forwards and backwards. Ignore non-alphanumeric characters and case sensitivity.
Input: "A man, a plan, a canal: Panama"
Output: true
Input: "race a car"
Output: false
// JavaScript - O(n) time, O(1) space
function isPalindrome(s) {
// Clean the string - keep only letters and numbers, lowercase
s = s.toLowerCase().replace(/[^a-z0-9]/g, "");
let left = 0, right = s.length - 1;
while (left < right) {
if (s[left] !== s[right]) return false;
left++;
right--;
}
return true;
}
isPalindrome("A man, a plan, a canal: Panama"); // true
isPalindrome("race a car"); // false
// Java
public boolean isPalindrome(String s) {
s = s.toLowerCase().replaceAll("[^a-z0-9]", "");
int left = 0, right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) return false;
left++;
right--;
}
return true;
}
Watch the video below for a clear step-by-step walkthrough with code:
Problem 3 - Check if Two Strings are Anagrams
Problem: Given two strings, return true if one is an anagram of the other - same characters, same frequency, different order.
Input: s = "anagram", t = "nagaram"
Output: true
Input: s = "rat", t = "car"
Output: false
// JavaScript - frequency map O(n) time
function isAnagram(s, t) {
if (s.length !== t.length) return false;
const count = {};
for (let char of s) {
count[char] = (count[char] || 0) + 1;
}
for (let char of t) {
if (!count[char]) return false;
count[char]--;
}
return true;
}
isAnagram("anagram", "nagaram"); // true
isAnagram("rat", "car"); // false
// Java
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) return false;
int[] count = new int[26]; // for lowercase a-z
for (char c : s.toCharArray()) count[c - 'a']++;
for (char c : t.toCharArray()) count[c - 'a']--;
for (int n : count) {
if (n != 0) return false;
}
return true;
}
Problem 4 - First Non-Repeating Character
Problem: Given a string, find the index of the first character that appears only once. Return -1 if none exists.
Input: "leetcode"
Output: 0 // 'l' appears only once
Input: "aabb"
Output: -1
// JavaScript - O(n) using frequency map
function firstUniqChar(s) {
const count = {};
// Count frequency of each character
for (let char of s) {
count[char] = (count[char] || 0) + 1;
}
// Find first character with frequency 1
for (let i = 0; i < s.length; i++) {
if (count[s[i]] === 1) return i;
}
return -1;
}
firstUniqChar("leetcode"); // 0
firstUniqChar("aabb"); // -1
Watch the video below for a clear step-by-step walkthrough with code:
Problem 5 - Longest Common Prefix
Problem: Given an array of strings, find the longest common prefix string among all of them.
Input: ["flower", "flow", "flight"]
Output: "fl"
Input: ["dog", "racecar", "car"]
Output: "" // no common prefix
// JavaScript - vertical scanning O(n * m)
function longestCommonPrefix(strs) {
if (!strs.length) return "";
let prefix = strs[0]; // start with first string as prefix
for (let i = 1; i < strs.length; i++) {
// Shrink prefix until current string starts with it
while (!strs[i].startsWith(prefix)) {
prefix = prefix.slice(0, -1); // remove last character
if (!prefix) return "";
}
}
return prefix;
}
longestCommonPrefix(["flower", "flow", "flight"]); // "fl"
longestCommonPrefix(["dog", "racecar", "car"]); // ""
Problem 6 - Valid Parentheses
Problem: Given a string containing only
(, ), {, },
[, ] - determine if the input is valid.
An input string is valid when every opening bracket has a matching
closing bracket in the correct order.
Input: "()" โ true
Input: "()[]{}" โ true
Input: "(]" โ false
Input: "([)]" โ false
// JavaScript - stack approach O(n)
function isValid(s) {
const stack = [];
const map = {
')': '(',
'}': '{',
']': '['
};
for (let char of s) {
if (char === '(' || char === '{' || char === '[') {
stack.push(char); // opening bracket - push to stack
} else {
// closing bracket - check if it matches the top of stack
if (stack.pop() !== map[char]) return false;
}
}
return stack.length === 0; // valid if stack is empty
}
isValid("()[]{}"); // true
isValid("([)]"); // false
Problem 7 - Longest Substring Without Repeating Characters
Problem: Find the length of the longest substring that contains no repeating characters.
Input: "abcabcbb"
Output: 3 // "abc"
Input: "bbbbb"
Output: 1 // "b"
Input: "pwwkew"
Output: 3 // "wke"
Use the sliding window technique with a Set to track characters in the current window:
// JavaScript - sliding window O(n)
function lengthOfLongestSubstring(s) {
const set = new Set();
let left = 0, maxLen = 0;
for (let right = 0; right < s.length; right++) {
// Shrink window from left until no duplicate
while (set.has(s[right])) {
set.delete(s[left]);
left++;
}
set.add(s[right]);
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
lengthOfLongestSubstring("abcabcbb"); // 3
lengthOfLongestSubstring("pwwkew"); // 3
// Java
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int left = 0, maxLen = 0;
for (int right = 0; right < s.length(); right++) {
while (set.contains(s.charAt(right))) {
set.remove(s.charAt(left));
left++;
}
set.add(s.charAt(right));
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
Problem 8 - Count and Say
Problem: The count-and-say sequence starts with "1". Each term is generated by reading the previous term aloud - counting consecutive digits. Generate the nth term.
n=1: "1"
n=2: "11" // one 1
n=3: "21" // two 1s
n=4: "1211" // one 2, one 1
n=5: "111221" // one 1, one 2, two 1s
// JavaScript
function countAndSay(n) {
let result = "1";
for (let i = 1; i < n; i++) {
let next = "";
let count = 1;
for (let j = 1; j <= result.length; j++) {
if (j < result.length && result[j] === result[j - 1]) {
count++;
} else {
next += count + result[j - 1];
count = 1;
}
}
result = next;
}
return result;
}
countAndSay(4); // "1211"
countAndSay(5); // "111221"
Problem 9 - String Compression
Problem: Compress a string by replacing consecutive repeated characters with the character followed by the count. If the compressed string is not smaller, return the original.
Input: "aabcccccaaa"
Output: "a2b1c5a3"
Input: "abc"
Output: "abc" // compressed "a1b1c1" is longer
// JavaScript - O(n)
function compressString(str) {
let compressed = "";
let count = 1;
for (let i = 0; i < str.length; i++) {
if (i + 1 < str.length && str[i] === str[i + 1]) {
count++;
} else {
compressed += str[i] + count;
count = 1;
}
}
return compressed.length < str.length ? compressed : str;
}
compressString("aabcccccaaa"); // "a2b1c5a3"
compressString("abc"); // "abc"
Problem 10 - Check if String is Rotation of Another
Problem: Given two strings, check if one is a rotation of the other.
Input: s1 = "abcde", s2 = "cdeab"
Output: true // "cdeab" is a rotation of "abcde"
Input: s1 = "abcde", s2 = "abced"
Output: false
// JavaScript - elegant trick: if s2 is a rotation of s1,
// then s2 will always appear as a substring in s1 + s1
function isRotation(s1, s2) {
if (s1.length !== s2.length) return false;
return (s1 + s1).includes(s2);
}
isRotation("abcde", "cdeab"); // true
isRotation("abcde", "abced"); // false
Problem 11 - Roman to Integer
Problem: Convert a Roman numeral string to an integer.
Input: "III" โ 3
Input: "IV" โ 4
Input: "IX" โ 9
Input: "LVIII" โ 58
Input: "MCMXCIV" โ 1994
// JavaScript - O(n)
function romanToInt(s) {
const map = {
'I': 1, 'V': 5, 'X': 10,
'L': 50, 'C': 100, 'D': 500,
'M': 1000
};
let result = 0;
for (let i = 0; i < s.length; i++) {
const current = map[s[i]];
const next = map[s[i + 1]];
// If current value is less than next - it's a subtractive pair (e.g. IV = 4)
if (next && current < next) {
result -= current;
} else {
result += current;
}
}
return result;
}
romanToInt("MCMXCIV"); // 1994
romanToInt("LVIII"); // 58
Problem 12 - Group Anagrams
Problem: Given an array of strings, group the anagrams together.
Input: ["eat", "tea", "tan", "ate", "nat", "bat"]
Output: [["bat"], ["nat","tan"], ["ate","eat","tea"]]
// JavaScript - sort each word as the key O(n * k log k)
function groupAnagrams(strs) {
const map = new Map();
for (let str of strs) {
// Sort characters to create a canonical key
const key = str.split("").sort().join("");
if (!map.has(key)) {
map.set(key, []);
}
map.get(key).push(str);
}
return Array.from(map.values());
}
groupAnagrams(["eat","tea","tan","ate","nat","bat"]);
// [["eat","tea","ate"], ["tan","nat"], ["bat"]]
// Java
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
char[] chars = s.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
map.computeIfAbsent(key, k -> new ArrayList<>()).add(s);
}
return new ArrayList<>(map.values());
}
Key Patterns to Master for String Interviews
| Pattern | When to Use | Problems |
|---|---|---|
| Two Pointers | Palindrome, reverse | Reverse String, Is Palindrome |
| Frequency Map | Character counting, anagrams | Anagram, First Unique Char, Group Anagrams |
| Sliding Window | Substrings, window conditions | Longest Substring, Min Window Substring |
| Stack | Matching brackets, nested structures | Valid Parentheses, Decode String |
| Sort as Key | Grouping anagrams | Group Anagrams, Anagram Check |
| String Concatenation Trick | Rotation problems | String Rotation, Repeated Substring |
Common String Interview Mistakes
- Not clarifying case sensitivity - always ask before writing any code. "Is 'A' the same as 'a'?" changes the entire approach.
-
Concatenating strings in a loop - in Java especially,
str += charinside a loop is O(nยฒ). Always useStringBuilderfor building strings character by character. - Forgetting empty string edge case - always test your solution against an empty string before finalizing.
- Assuming ASCII only - if the problem says Unicode, a simple 26-element array for character counting will not work. Use a HashMap instead.
-
Modifying a string in place in Java - strings are
immutable in Java. Convert to
char[]first if you need in-place modification.
Final Thought
String problems test the same core instincts as array problems - frequency maps, two pointers, sliding windows. The main difference is that strings have character-specific nuances: case sensitivity, encoding, immutability in certain languages, and the temptation to concatenate in loops which silently kills performance.
Practice these 12 problems until the patterns feel automatic. When you see a substring problem in an interview your first thought should be "sliding window." When you see anagram or frequency - "HashMap." When you see palindrome - "two pointers from both ends." That instinct is what separates a prepared candidate from an unprepared one.
Also check our Array Coding Interview Problems guide - the patterns from both guides together cover about 70% of what you will see in real technical interviews.
Have a specific string problem you are stuck on? Drop us a message on our contact page - we will walk you through it.
๐ You Might Also Like
- โ Best Google AdSense Alternative 2026 - Monetag Review for Publishers miscellaneous
- โ How to Start Freelancing as a Web Developer in 2026 (Complete Beginner's Guide) miscellaneous
- โ HTTP QUERY Method (RFC 10008) โ The New HTTP Method Every Developer Should Know miscellaneous
- โ JavaScript Array Methods Cheat Sheet โ Complete Guide with Example javascript
- โ MyLync โ Best Free Linktree Alternative for Developers, Creators & Businesses miscellaneous