Coding Interview Questions
Reverse a string without using reverse().
Example
Two pointers swapping characters from both ends: O(n) time.
public class Main {
static String reverse(String s) {
char[] c = s.toCharArray();
for (int i = 0, j = c.length - 1; i < j; i++, j--) {
char t = c[i]; c[i] = c[j]; c[j] = t;
}
return new String(c);
}
public static void main(String[] args) {
System.out.println(reverse("Careeroza"));
System.out.println(reverse("Java 21"));
}
}Output
azoreeraC 12 avaJ
Check whether a string is a palindrome.
Example
Ignore case and non-alphanumeric characters, compare from both ends.
public class Main {
static boolean isPalindrome(String s) {
String t = s.toLowerCase().replaceAll("[^a-z0-9]", "");
int i = 0, j = t.length() - 1;
while (i < j) {
if (t.charAt(i++) != t.charAt(j--)) return false;
}
return true;
}
public static void main(String[] args) {
for (String s : new String[] {"madam", "Java", "A man, a plan, a canal: Panama"}) {
System.out.println(s + " -> " + isPalindrome(s));
}
}
}Output
madam -> true Java -> false A man, a plan, a canal: Panama -> true
Print the first N Fibonacci numbers (iterative and recursive).
Example
Iterative is O(n); naive recursion is O(2^n), so memoise it.
import java.util.*;
public class Main {
static Map<Integer, Long> memo = new HashMap<>();
static long fib(int n) {
if (n < 2) return n;
if (memo.containsKey(n)) return memo.get(n);
long v = fib(n - 1) + fib(n - 2);
memo.put(n, v);
return v;
}
public static void main(String[] args) {
long a = 0, b = 1;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append(a).append(' ');
long next = a + b; a = b; b = next;
}
System.out.println("Iterative: " + sb.toString().trim());
System.out.println("fib(50) with memo: " + fib(50));
}
}Output
Iterative: 0 1 1 2 3 5 8 13 21 34 fib(50) with memo: 12586269025
Check whether two strings are anagrams.
Example
Count characters with an int[26] array: O(n) time, O(1) space.
public class Main {
static boolean isAnagram(String a, String b) {
a = a.replace(" ", "").toLowerCase();
b = b.replace(" ", "").toLowerCase();
if (a.length() != b.length()) return false;
int[] count = new int[26];
for (int i = 0; i < a.length(); i++) {
count[a.charAt(i) - 'a']++;
count[b.charAt(i) - 'a']--;
}
for (int c : count) if (c != 0) return false;
return true;
}
public static void main(String[] args) {
System.out.println(isAnagram("listen", "silent"));
System.out.println(isAnagram("Dormitory", "dirty room"));
System.out.println(isAnagram("hello", "world"));
}
}Output
true true false
Find duplicate elements in an array.
Example
A Set rejects elements it already has; LinkedHashSet keeps output order stable.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
int[] nums = {4, 2, 7, 2, 9, 4, 4, 1};
Set<Integer> seen = new HashSet<>();
Set<Integer> dups = new LinkedHashSet<>();
for (int n : nums) {
if (!seen.add(n)) dups.add(n);
}
System.out.println("Loop: " + dups);
Set<Integer> seen2 = new HashSet<>();
List<Integer> viaStream = Arrays.stream(nums).boxed()
.filter(n -> !seen2.add(n))
.distinct()
.collect(Collectors.toList());
System.out.println("Streams: " + viaStream);
}
}Output
Loop: [2, 4] Streams: [2, 4]
Find the second largest number in an array.
Example
Single pass tracking the largest and second largest distinct values.
import java.util.*;
public class Main {
static int secondLargest(int[] arr) {
int first = Integer.MIN_VALUE, second = Integer.MIN_VALUE;
for (int n : arr) {
if (n > first) { second = first; first = n; }
else if (n > second && n != first) second = n;
}
if (second == Integer.MIN_VALUE) throw new IllegalArgumentException("No second largest");
return second;
}
public static void main(String[] args) {
System.out.println(secondLargest(new int[] {12, 35, 1, 10, 34, 1}));
System.out.println(secondLargest(new int[] {10, 10, 5}));
int[] a = {12, 35, 1, 10, 34, 1};
System.out.println(Arrays.stream(a).boxed().distinct()
.sorted(Comparator.reverseOrder()).skip(1).findFirst().orElseThrow());
}
}Output
34 5 34
Count the frequency of each character using streams.
Example
groupingBy with a LinkedHashMap keeps the first-seen order.
import java.util.*;
import java.util.function.Function;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
String s = "programming";
Map<Character, Long> freq = s.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()));
System.out.println(freq);
Character firstNonRepeated = freq.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(Map.Entry::getKey)
.findFirst().orElse(null);
System.out.println("First non-repeated: " + firstNonRepeated);
}
}Output
{p=1, r=2, o=1, g=2, a=1, m=2, i=1, n=1}
First non-repeated: pCount word frequency in a sentence and find the most frequent word.
Example
Split, group and count with a TreeMap for sorted output.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
String text = "java is fun and java is powerful and java runs everywhere";
Map<String, Long> counts = Arrays.stream(text.split("\\s+"))
.collect(Collectors.groupingBy(w -> w, TreeMap::new, Collectors.counting()));
System.out.println(counts);
String top = counts.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey).orElse("");
System.out.println("Most frequent: " + top);
}
}Output
{and=2, everywhere=1, fun=1, is=2, java=3, powerful=1, runs=1}
Most frequent: javaCheck if a number is prime and print primes up to 30.
Example
Only test divisors up to the square root.
public class Main {
static boolean isPrime(int n) {
if (n < 2) return false;
for (int i = 2; (long) i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 30; i++) if (isPrime(i)) sb.append(i).append(' ');
System.out.println(sb.toString().trim());
System.out.println("97 prime? " + isPrime(97));
}
}Output
2 3 5 7 11 13 17 19 23 29 97 prime? true
Swap two numbers without a third variable.
Example
Arithmetic and XOR approaches.
public class Main {
public static void main(String[] args) {
int a = 5, b = 9;
a = a + b; b = a - b; a = a - b;
System.out.println("After +/-: a=" + a + ", b=" + b);
a ^= b; b ^= a; a ^= b;
System.out.println("After XOR: a=" + a + ", b=" + b);
}
}Output
After +/-: a=9, b=5 After XOR: a=5, b=9
Find the missing number in an array of 1..N.
Example
Expected sum minus actual sum. Use long to avoid overflow for big N.
public class Main {
static int missing(int[] arr, int n) {
long expected = (long) n * (n + 1) / 2;
long actual = 0;
for (int x : arr) actual += x;
return (int) (expected - actual);
}
public static void main(String[] args) {
System.out.println(missing(new int[] {1, 2, 4, 5, 6}, 6));
System.out.println(missing(new int[] {2, 3, 1, 5}, 5));
}
}Output
3 4
Group employees by department and find the highest-paid in each (Java 8 streams).
Example
A very common stream question at product companies.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Emp> emps = List.of(
new Emp("Asha", "IT", 90000), new Emp("Ravi", "IT", 75000),
new Emp("Neha", "HR", 50000), new Emp("Kiran", "Sales", 60000),
new Emp("Vikram", "Sales", 82000));
Map<String, Long> countByDept = emps.stream()
.collect(Collectors.groupingBy(Emp::dept, TreeMap::new, Collectors.counting()));
System.out.println("Count: " + countByDept);
Map<String, String> topByDept = emps.stream()
.collect(Collectors.groupingBy(Emp::dept, TreeMap::new,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparingDouble(Emp::salary)),
o -> o.map(Emp::name).orElse("-"))));
System.out.println("Top paid: " + topByDept);
double avg = emps.stream().mapToDouble(Emp::salary).average().orElse(0);
System.out.printf("Average salary: %.1f%n", avg);
}
}
record Emp(String name, String dept, double salary) {}Output
Count: {HR=1, IT=2, Sales=2}
Top paid: {HR=Neha, IT=Asha, Sales=Vikram}
Average salary: 71400.0