Ad – 728×90
🎯 Interview Prep

JavaScript Coding Challenges – Practice with Real Solutions

Twenty carefully selected coding challenges across strings, arrays, numbers, objects, and algorithms — each with a clean JavaScript solution, output, and explanation. Work through them in order or jump to a category you want to strengthen.

⏱️ 35 min read 🎯 Advanced 📅 Updated 2026

String Challenges

String manipulation is one of the most tested areas in JavaScript interviews. These challenges cover common patterns: reversal, character frequency, transformation, and validation.

Challenge: Reverse a String

Write a function that reverses a string without using the built-in .reverse() method directly on the string.

JavaScript
function reverseString(str) {
  return str.split("").reverse().join("");
}

// Without .reverse():
function reverseStringManual(str) {
  let result = "";
  for (let i = str.length - 1; i >= 0; i--) {
    result += str[i];
  }
  return result;
}

console.log(reverseString("hello"));        // "olleh"
console.log(reverseStringManual("JavaScript")); // "tpircSavaJ"
Output:
"olleh"
"tpircSavaJ"

Challenge: Check Palindrome

Return true if the string reads the same forwards and backwards. Ignore spaces, punctuation, and case.

JavaScript
function isPalindrome(str) {
  const cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, "");
  return cleaned === cleaned.split("").reverse().join("");
}

console.log(isPalindrome("racecar"));           // true
console.log(isPalindrome("A man a plan a canal Panama")); // true
console.log(isPalindrome("hello"));             // false
Output:
true
true
false

Challenge: Count Vowels

Count the number of vowels (a, e, i, o, u) in a string (case-insensitive).

JavaScript
function countVowels(str) {
  return (str.match(/[aeiou]/gi) || []).length;
}

console.log(countVowels("JavaScript")); // 3
console.log(countVowels("rhythm"));     // 0
console.log(countVowels("Hello World")); // 3
Output:
3
0
3

Challenge: Capitalize Every Word

Capitalize the first letter of every word in a string (title case).

JavaScript
function capitalizeWords(str) {
  return str
    .split(" ")
    .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
    .join(" ");
}

console.log(capitalizeWords("hello world"));       // "Hello World"
console.log(capitalizeWords("the quick brown fox")); // "The Quick Brown Fox"
Output:
"Hello World"
"The Quick Brown Fox"

Challenge: Find Most Frequent Character

Return the character that appears most frequently in a string. If there's a tie, return the first one.

JavaScript
function mostFrequentChar(str) {
  const freq = {};
  for (const char of str) {
    freq[char] = (freq[char] || 0) + 1;
  }
  return Object.entries(freq).reduce((max, curr) =>
    curr[1] > max[1] ? curr : max
  )[0];
}

console.log(mostFrequentChar("aabbcccdd")); // "c"
console.log(mostFrequentChar("javascript")); // "a"
Output:
"c"
"a"

Array Challenges

Array manipulation tests your knowledge of iteration, higher-order functions, and algorithmic thinking. Master these patterns and you'll handle the majority of interview array questions.

Challenge: Flatten a Nested Array

Flatten an arbitrarily deeply nested array into a single-level array.

JavaScript
// Modern approach
function flatten(arr) {
  return arr.flat(Infinity);
}

// Recursive approach (classic interview answer)
function flattenRecursive(arr) {
  return arr.reduce((acc, val) =>
    Array.isArray(val) ? acc.concat(flattenRecursive(val)) : acc.concat(val), []);
}

const nested = [1, [2, [3, [4, [5]]]]];
console.log(flatten(nested));          // [1, 2, 3, 4, 5]
console.log(flattenRecursive(nested)); // [1, 2, 3, 4, 5]
Output:
[1, 2, 3, 4, 5]

Challenge: Find Duplicates

Return an array of all duplicate values in an array.

JavaScript
function findDuplicates(arr) {
  const seen = new Set();
  const duplicates = new Set();
  for (const item of arr) {
    if (seen.has(item)) duplicates.add(item);
    else seen.add(item);
  }
  return [...duplicates];
}

console.log(findDuplicates([1, 2, 3, 2, 4, 3, 5])); // [2, 3]
console.log(findDuplicates(["a", "b", "a", "c"]));   // ["a"]
Output:
[2, 3]
["a"]

Challenge: Rotate Array

Rotate an array to the right by k positions.

JavaScript
function rotateArray(arr, k) {
  const n = arr.length;
  const steps = k % n; // handle k > n
  return [...arr.slice(n - steps), ...arr.slice(0, n - steps)];
}

console.log(rotateArray([1, 2, 3, 4, 5], 2)); // [4, 5, 1, 2, 3]
console.log(rotateArray([1, 2, 3], 4));        // [3, 1, 2]
Output:
[4, 5, 1, 2, 3]
[3, 1, 2]

Challenge: Chunk Array

Split an array into chunks of a given size.

JavaScript
function chunkArray(arr, size) {
  const chunks = [];
  for (let i = 0; i < arr.length; i += size) {
    chunks.push(arr.slice(i, i + size));
  }
  return chunks;
}

console.log(chunkArray([1,2,3,4,5,6,7], 3)); // [[1,2,3],[4,5,6],[7]]
console.log(chunkArray([1,2,3,4], 2));        // [[1,2],[3,4]]
Output:
[[1,2,3],[4,5,6],[7]]
[[1,2],[3,4]]

Challenge: Group Anagrams

Given an array of strings, group anagrams together.

JavaScript
function groupAnagrams(words) {
  const map = new Map();
  for (const word of words) {
    const key = word.split("").sort().join("");
    if (!map.has(key)) map.set(key, []);
    map.get(key).push(word);
  }
  return [...map.values()];
}

console.log(groupAnagrams(["eat","tea","tan","ate","nat","bat"]));
// [["eat","tea","ate"], ["tan","nat"], ["bat"]]
Output:
[["eat","tea","ate"], ["tan","nat"], ["bat"]]
Ad – 336×280

Number Challenges

Challenge: FizzBuzz

Print numbers 1–100. For multiples of 3 print "Fizz", multiples of 5 print "Buzz", multiples of both print "FizzBuzz".

JavaScript
function fizzBuzz(n = 100) {
  for (let i = 1; i <= n; i++) {
    if (i % 15 === 0)      console.log("FizzBuzz");
    else if (i % 3 === 0)  console.log("Fizz");
    else if (i % 5 === 0)  console.log("Buzz");
    else                   console.log(i);
  }
}
fizzBuzz(15);
// 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz

Challenge: Fibonacci Sequence

Return the first n numbers of the Fibonacci sequence. Implement both recursive and iterative approaches.

JavaScript
// Iterative (efficient)
function fibonacci(n) {
  const seq = [0, 1];
  for (let i = 2; i < n; i++) {
    seq.push(seq[i - 1] + seq[i - 2]);
  }
  return seq.slice(0, n);
}

// Recursive with memoization
function fibMemo(n, memo = {}) {
  if (n <= 1) return n;
  if (memo[n]) return memo[n];
  memo[n] = fibMemo(n - 1, memo) + fibMemo(n - 2, memo);
  return memo[n];
}

console.log(fibonacci(8));   // [0, 1, 1, 2, 3, 5, 8, 13]
console.log(fibMemo(10));    // 55
Output:
[0, 1, 1, 2, 3, 5, 8, 13]
55

Challenge: Check Prime Number

Return true if a number is prime.

JavaScript
function isPrime(n) {
  if (n < 2) return false;
  if (n === 2) return true;
  if (n % 2 === 0) return false;
  for (let i = 3; i <= Math.sqrt(n); i += 2) {
    if (n % i === 0) return false;
  }
  return true;
}

console.log(isPrime(2));   // true
console.log(isPrime(17));  // true
console.log(isPrime(18));  // false
console.log(isPrime(1));   // false
Output:
true
true
false
false

Object Challenges

Challenge: Deep Clone an Object

Clone an object so that nested modifications do not affect the original.

JavaScript
function deepClone(obj) {
  if (obj === null || typeof obj !== "object") return obj;
  if (Array.isArray(obj)) return obj.map(deepClone);
  return Object.fromEntries(
    Object.entries(obj).map(([k, v]) => [k, deepClone(v)])
  );
}

const original = { a: 1, b: { c: 2, d: [3, 4] } };
const clone = deepClone(original);
clone.b.c = 99;
console.log(original.b.c); // 2 (untouched)
console.log(clone.b.c);    // 99
Output:
2
99

Challenge: Pick / Omit Keys from Object

Implement pick(obj, keys) and omit(obj, keys) utilities.

JavaScript
const pick = (obj, keys) =>
  Object.fromEntries(keys.filter(k => k in obj).map(k => [k, obj[k]]));

const omit = (obj, keys) =>
  Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));

const user = { id: 1, name: "Alice", email: "alice@example.com", password: "secret" };

console.log(pick(user, ["id", "name"]));         // { id: 1, name: "Alice" }
console.log(omit(user, ["password", "email"]));  // { id: 1, name: "Alice" }
Output:
{ id: 1, name: "Alice" }
{ id: 1, name: "Alice" }

Challenge: Group Array of Objects by Property

Group an array of objects by a specified property key.

JavaScript
function groupBy(arr, key) {
  return arr.reduce((groups, item) => {
    const groupKey = item[key];
    if (!groups[groupKey]) groups[groupKey] = [];
    groups[groupKey].push(item);
    return groups;
  }, {});
}

const people = [
  { name: "Alice", dept: "Engineering" },
  { name: "Bob",   dept: "Marketing" },
  { name: "Carol", dept: "Engineering" },
  { name: "Dave",  dept: "Marketing" },
];

console.log(groupBy(people, "dept"));
// {
//   Engineering: [{ name: "Alice"... }, { name: "Carol"... }],
//   Marketing:   [{ name: "Bob"... },  { name: "Dave"... }]
// }

Algorithm Challenges

Challenge: Binary Search

Implement binary search on a sorted array. Return the index of the target, or -1 if not found. Time complexity: O(log n).

JavaScript
function binarySearch(arr, target) {
  let left = 0;
  let right = arr.length - 1;

  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (arr[mid] === target) return mid;
    if (arr[mid] < target) left = mid + 1;
    else right = mid - 1;
  }
  return -1;
}

const sorted = [1, 3, 5, 7, 9, 11, 13, 15];
console.log(binarySearch(sorted, 7));  // 3
console.log(binarySearch(sorted, 10)); // -1
Output:
3
-1

Challenge: Two-Sum Problem

Given an array of integers and a target sum, return the indices of the two numbers that add up to the target. Each input has exactly one solution.

JavaScript
function twoSum(nums, target) {
  const seen = new Map(); // value -> index
  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i];
    if (seen.has(complement)) {
      return [seen.get(complement), i];
    }
    seen.set(nums[i], i);
  }
  return [];
}

console.log(twoSum([2, 7, 11, 15], 9));  // [0, 1]
console.log(twoSum([3, 2, 4], 6));        // [1, 2]
Output:
[0, 1]
[1, 2]

Challenge: Valid Parentheses

Given a string containing only (, ), {, }, [, ], determine if the input is valid (every open bracket has a matching close bracket in the correct order).

JavaScript
function isValidParentheses(s) {
  const stack = [];
  const pairs = { ")": "(", "}": "{", "]": "[" };

  for (const char of s) {
    if ("([{".includes(char)) {
      stack.push(char);
    } else {
      if (stack.pop() !== pairs[char]) return false;
    }
  }
  return stack.length === 0;
}

console.log(isValidParentheses("()[]{}"));   // true
console.log(isValidParentheses("([{}])"));   // true
console.log(isValidParentheses("([)]"));     // false
console.log(isValidParentheses("{[]"));      // false
Output:
true
true
false
false
Pattern Recognition: Many interview problems map to a small set of patterns — sliding window, two pointers, hash map for O(1) lookup, stack for matching pairs, and binary search. Recognizing the pattern is often more valuable than knowing a specific algorithm by heart.
Time Complexity: Always state the time and space complexity of your solution. Using a hash map typically reduces O(n²) brute-force solutions to O(n). Interviewers specifically look for this optimization step.

Challenge Reference Table

ChallengeCategoryKey TechniqueTime Complexity
Reverse StringStringsplit/reverse/joinO(n)
PalindromeStringTwo-pointer / regexO(n)
Most Frequent CharStringFrequency mapO(n)
Find DuplicatesArraySetO(n)
Group AnagramsArraySort + MapO(n·k log k)
Binary SearchAlgorithmDivide and conquerO(log n)
Two SumAlgorithmHash mapO(n)
Valid ParenthesesAlgorithmStackO(n)

Practice Strategy

Work through these challenges in this order:

  1. Attempt each challenge for 10–15 minutes without looking at the solution.
  2. Study the solution and understand the algorithm, not just the code.
  3. Re-implement from memory the next day.
  4. Identify the underlying pattern (hash map, stack, two pointers, etc.).
  5. Apply that pattern to a new, similar problem.

Bonus Challenges

Once you're comfortable with the above, try these harder variations:

  • Longest substring without repeating characters (sliding window)
  • Merge two sorted arrays in O(n) time
  • Find the k-th largest element in an array
  • Implement a LRU (Least Recently Used) cache

FAQ

How should I approach a coding challenge I've never seen?

Clarify the problem, identify examples and edge cases, choose a brute-force approach first, then optimize. Talking through your reasoning aloud shows the interviewer how you think.

Should I use built-in methods like .sort() in interviews?

Yes, unless the interviewer specifically asks you to implement from scratch. Using built-ins demonstrates practical knowledge. Mention the underlying complexity (.sort() is O(n log n)).

What's the most important data structure to know for JS interviews?

The hash map (Map/Object) is the most versatile. A huge number of O(n) solutions require trading space for time using a hash map. Master it deeply.

How do I get faster at coding challenges?

Consistency beats intensity. Twenty minutes of daily practice for four weeks produces more improvement than a 14-hour weekend cram session.

Is it okay to ask questions during a coding interview?

Not just okay — expected. Clarifying assumptions (can values be negative? is the array sorted?) prevents you from solving the wrong problem and shows professional engineering instincts.

Summary

  • String patterns: reversal, character frequency maps, regex for cleaning
  • Array patterns: Set for uniqueness, reduce for aggregation, slice for sub-arrays
  • Number patterns: modulo for divisibility, sqrt optimization for primality
  • Object patterns: reduce for grouping, entries/fromEntries for transformation
  • Algorithm patterns: binary search (O(log n)), hash map (O(1) lookup), stack for matching
  • Use const by default — switch to let only when reassignment is needed
  • Prefer Map over plain objects when keys are dynamic
  • Handle edge cases explicitly: empty input, single element, all duplicates
  • State the time and space complexity before or after writing your solution
  • Test your solution with at least two examples including an edge case