Java Coding for SDET — 30 Solutions (with Explanations)¶
Goal: be able to WRITE each one from a blank editor AND EXPLAIN it out loud; practice by deleting the method body and re-implementing.
Q1. Reverse a String without using reverse() method¶
Approach: Walk from the last index to the first and append each char; O(n) time, O(n) space.
public class Q1 {
static String reverse(String s) {
char[] c = s.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = c.length - 1; i >= 0; i--) sb.append(c[i]);
return sb.toString();
}
public static void main(String[] a) {
System.out.println(reverse("hello")); // olleh
}
}
Say it aloud: "I read the char array back-to-front into a StringBuilder — no built-in reverse needed."
Q2. Check if a String is a palindrome¶
Approach: Two pointers from both ends moving inward; stop on first mismatch. O(n) time, O(1) space.
public class Q2 {
static boolean isPalindrome(String s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (s.charAt(i) != s.charAt(j)) return false;
i++; j--;
}
return true;
}
public static void main(String[] a) {
System.out.println(isPalindrome("madam")); // true
System.out.println(isPalindrome("hello")); // false
}
}
Say it aloud: "Two pointers converge; if any pair differs it isn't a palindrome."
Q3. Find duplicate characters in a String¶
Approach: Count chars in a HashMap, then print those with count > 1. O(n) time.
import java.util.*;
public class Q3 {
static void printDuplicates(String s) {
Map<Character, Integer> map = new LinkedHashMap<>();
for (char c : s.toCharArray()) map.merge(c, 1, Integer::sum);
for (Map.Entry<Character, Integer> e : map.entrySet())
if (e.getValue() > 1) System.out.println(e.getKey() + " -> " + e.getValue());
}
public static void main(String[] a) {
printDuplicates("programming"); // r->2, g->2, m->2
}
}
Say it aloud: "I tally every char in a map, then report keys whose count exceeds one."
Q4. Count the occurrence of each character in a String¶
Approach: HashMap with merge to increment counts in a single pass. O(n) time.
import java.util.*;
public class Q4 {
static Map<Character, Integer> count(String s) {
Map<Character, Integer> map = new LinkedHashMap<>();
for (char c : s.toCharArray()) map.merge(c, 1, Integer::sum);
return map;
}
public static void main(String[] a) {
System.out.println(count("banana")); // {b=1, a=3, n=2}
}
}
Say it aloud: "One pass, map.merge(c, 1, Integer::sum) builds the frequency table."
Q5. Check if two Strings are anagrams¶
Approach: Sort both char arrays and compare (O(n log n)); or compare frequency maps. Ignore case/spaces if asked.
import java.util.*;
public class Q5 {
static boolean isAnagram(String a, String b) {
char[] x = a.replaceAll("\\s", "").toLowerCase().toCharArray();
char[] y = b.replaceAll("\\s", "").toLowerCase().toCharArray();
Arrays.sort(x); Arrays.sort(y);
return Arrays.equals(x, y);
}
public static void main(String[] a) {
System.out.println(isAnagram("listen", "silent")); // true
}
}
Say it aloud: "Anagrams share the same letters, so sorted char arrays must be equal."
Q6. Find the first non-repeated character in a String¶
Approach: Build an ordered count map, then return the first key with count 1. O(n) time.
import java.util.*;
public class Q6 {
static Character firstNonRepeated(String s) {
Map<Character, Integer> map = new LinkedHashMap<>();
for (char c : s.toCharArray()) map.merge(c, 1, Integer::sum);
for (Map.Entry<Character, Integer> e : map.entrySet())
if (e.getValue() == 1) return e.getKey();
return null;
}
public static void main(String[] a) {
System.out.println(firstNonRepeated("swiss")); // w
}
}
Say it aloud: "LinkedHashMap keeps insertion order, so the first count-1 key is the answer."
Q7. Reverse each word in a sentence¶
Approach: Split on spaces, reverse each token with StringBuilder, join back. O(n) time.
public class Q7 {
static String reverseWords(String s) {
String[] words = s.split(" ");
StringBuilder out = new StringBuilder();
for (int i = 0; i < words.length; i++) {
out.append(new StringBuilder(words[i]).reverse());
if (i < words.length - 1) out.append(" ");
}
return out.toString();
}
public static void main(String[] a) {
System.out.println(reverseWords("Java is fun")); // avaJ si nuf
}
}
Say it aloud: "Split into words, reverse each word individually, keep the original word order."
Q8. Remove all whitespaces from a String¶
Approach: Regex replace of \s with empty; O(n) time.
public class Q8 {
static String removeSpaces(String s) {
return s.replaceAll("\\s", ""); // \s covers space, tab, newline
}
public static void main(String[] a) {
System.out.println(removeSpaces("a b\tc\nd")); // abcd
}
}
Say it aloud: "replaceAll(\"\\\\s\", \"\") strips every whitespace character in one shot."
Q9. Swap two numbers without using a third variable¶
Approach: Use arithmetic (a=a+b; b=a-b; a=a-b) or XOR to avoid a temp. O(1).
public class Q9 {
public static void main(String[] a) {
int x = 5, y = 9;
x = x + y; // 14
y = x - y; // 5
x = x - y; // 9
System.out.println("x=" + x + " y=" + y); // x=9 y=5
}
}
Say it aloud: "Sum then subtract recovers each value; XOR works too but arithmetic reads clearest."
Q10. Find the factorial of a number using recursion¶
Approach: fact(n) = n * fact(n-1) with base case fact(0)=1. O(n) calls; use long for range.
public class Q10 {
static long factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
public static void main(String[] a) {
System.out.println(factorial(5)); // 120
}
}
Say it aloud: "Base case at 0/1, otherwise n times the factorial of n-1."
Q11. Check if a number is prime¶
Approach: Trial-divide only up to sqrt(n); handle n<2. O(sqrt(n)).
public class Q11 {
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[] a) {
System.out.println(isPrime(29)); // true
System.out.println(isPrime(15)); // false
}
}
Say it aloud: "A factor above sqrt(n) implies one below it, so I only test up to sqrt(n)."
Q12. Print Fibonacci series up to N terms¶
Approach: Iterate keeping the last two values; O(n) time, O(1) space.
public class Q12 {
static void fibonacci(int n) {
int a = 0, b = 1;
for (int i = 0; i < n; i++) {
System.out.print(a + " ");
int next = a + b;
a = b; b = next;
}
}
public static void main(String[] a) {
fibonacci(8); // 0 1 1 2 3 5 8 13
}
}
Say it aloud: "I carry two running values and slide the window forward n times."
Q13. Check if a number is an Armstrong number¶
Approach: Sum each digit raised to the power of the digit-count; equals original if Armstrong (153 = 1^3+5^3+3^3). O(d) time.
public class Q13 {
static boolean isArmstrong(int n) {
int digits = String.valueOf(n).length();
int sum = 0, temp = n;
while (temp > 0) {
int d = temp % 10;
int p = 1;
for (int k = 0; k < digits; k++) p *= d; // integer power — avoids Math.pow (double) rounding
sum += p;
temp /= 10;
}
return sum == n;
}
public static void main(String[] a) {
System.out.println(isArmstrong(153)); // true
System.out.println(isArmstrong(123)); // false
}
}
Say it aloud: "Raise each digit to the count of digits, sum them, compare to the original."
Q14. Find the largest and smallest number in an array¶
Approach: Single pass tracking running min and max. O(n) time.
public class Q14 {
static void minMax(int[] arr) {
int min = arr[0], max = arr[0];
for (int x : arr) {
if (x < min) min = x;
if (x > max) max = x;
}
System.out.println("min=" + min + " max=" + max);
}
public static void main(String[] a) {
minMax(new int[]{3, 7, 1, 9, 4}); // min=1 max=9
}
}
Say it aloud: "One pass, update min and max as I go — no sorting needed."
Q15. Sort an array without using sort() method¶
Approach: Bubble sort — swap adjacent out-of-order pairs until stable. O(n^2), fine for interview demos.
public class Q15 {
static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++)
for (int j = 0; j < arr.length - 1 - i; j++)
if (arr[j] > arr[j + 1]) {
int t = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = t;
}
}
public static void main(String[] a) {
int[] arr = {5, 2, 8, 1, 4};
bubbleSort(arr);
System.out.println(java.util.Arrays.toString(arr)); // [1, 2, 4, 5, 8]
}
}
Say it aloud: "Bubble the largest element to the end each pass by swapping neighbors."
Q16. Find duplicate elements in an array¶
Approach: Track seen values in a HashSet; if add returns false it's a duplicate. O(n) time.
import java.util.*;
public class Q16 {
static Set<Integer> findDuplicates(int[] arr) {
Set<Integer> seen = new HashSet<>(), dups = new LinkedHashSet<>();
for (int x : arr) if (!seen.add(x)) dups.add(x);
return dups;
}
public static void main(String[] a) {
System.out.println(findDuplicates(new int[]{1, 2, 3, 2, 4, 1})); // [2, 1] (first-detected-duplicate order)
}
}
Say it aloud: "A HashSet add returning false means I've already seen that value."
Q17. Check if two arrays are equal¶
Approach: Same length and same element order → Arrays.equals; if order-insensitive, sort first. O(n).
import java.util.*;
public class Q17 {
static boolean equalIgnoringOrder(int[] a, int[] b) {
if (a.length != b.length) return false;
int[] x = a.clone(), y = b.clone();
Arrays.sort(x); Arrays.sort(y);
return Arrays.equals(x, y);
}
public static void main(String[] a) {
System.out.println(Arrays.equals(new int[]{1,2,3}, new int[]{1,2,3})); // true (order-sensitive)
System.out.println(equalIgnoringOrder(new int[]{1,2,3}, new int[]{3,2,1})); // true
}
}
Say it aloud: "Arrays.equals checks order-sensitive equality; sorting clones first makes it order-insensitive."
Q18. Find the second highest number in an array¶
Approach: Single pass tracking highest and second-highest. O(n) time.
public class Q18 {
static int secondHighest(int[] arr) {
int first = Integer.MIN_VALUE, second = Integer.MIN_VALUE;
for (int x : arr) {
if (x > first) { second = first; first = x; }
else if (x > second && x != first) second = x;
}
return second;
}
public static void main(String[] a) {
System.out.println(secondHighest(new int[]{10, 5, 20, 8, 20})); // 10
}
}
Say it aloud: "Two trackers; when a new max appears the old max slides into second place."
Q19. Remove duplicates from an array¶
Approach: Feed values into a LinkedHashSet (keeps order, drops repeats), then back to array. O(n).
import java.util.*;
public class Q19 {
static int[] removeDuplicates(int[] arr) {
Set<Integer> set = new LinkedHashSet<>();
for (int x : arr) set.add(x);
return set.stream().mapToInt(Integer::intValue).toArray();
}
public static void main(String[] a) {
System.out.println(Arrays.toString(removeDuplicates(new int[]{1, 2, 2, 3, 1}))); // [1, 2, 3]
}
}
Say it aloud: "A LinkedHashSet dedupes while preserving first-seen order."
Q20. Reverse an array¶
Approach: Swap symmetric pairs from both ends toward the middle. O(n) time, O(1) space.
import java.util.Arrays;
public class Q20 {
static void reverse(int[] arr) {
int i = 0, j = arr.length - 1;
while (i < j) {
int t = arr[i]; arr[i] = arr[j]; arr[j] = t;
i++; j--;
}
}
public static void main(String[] a) {
int[] arr = {1, 2, 3, 4, 5};
reverse(arr);
System.out.println(Arrays.toString(arr)); // [5, 4, 3, 2, 1]
}
}
Say it aloud: "Swap the i-th and j-th elements while the pointers move inward."
Q21. Implement a custom logic to convert String to Integer (like Integer.parseInt)¶
Approach: Handle optional sign, then accumulate result = result*10 + digit; throw on non-digits. O(n).
public class Q21 {
static int parseInt(String s) {
if (s == null || s.isEmpty()) throw new NumberFormatException("empty");
int i = 0, sign = 1;
if (s.charAt(0) == '-' || s.charAt(0) == '+') {
sign = s.charAt(0) == '-' ? -1 : 1;
i++;
}
long result = 0;
for (; i < s.length(); i++) {
char c = s.charAt(i);
if (c < '0' || c > '9') throw new NumberFormatException("bad char: " + c);
result = result * 10 + (c - '0');
}
return (int) (sign * result);
}
public static void main(String[] a) {
System.out.println(parseInt("-1234")); // -1234
}
}
Say it aloud: "Read the sign, then build the number digit-by-digit as value*10 plus (char - '0')."
Q22. Check for balanced parentheses using Stack¶
Approach: Push openers; on a closer, pop and verify it matches. Balanced iff every closer matches and the stack ends empty. O(n).
import java.util.*;
public class Q22 {
static boolean isBalanced(String s) {
Deque<Character> stack = new ArrayDeque<>();
Map<Character, Character> pairs = Map.of(')', '(', ']', '[', '}', '{');
for (char c : s.toCharArray()) {
if (c == '(' || c == '[' || c == '{') stack.push(c);
else if (pairs.containsKey(c)) {
if (stack.isEmpty() || stack.pop() != pairs.get(c)) return false;
}
}
return stack.isEmpty();
}
public static void main(String[] a) {
System.out.println(isBalanced("{[()]}")); // true
System.out.println(isBalanced("{[(])}")); // false
}
}
Say it aloud: "Push openers on a Deque; each closer must pop its matching opener, and the stack must end empty."
Q23. Implement a basic LinkedList (add, delete, print)¶
Approach: Singly linked nodes with head pointer; add appends to tail, delete unlinks first match. O(n) traversal.
public class Q23 {
static class Node { int val; Node next; Node(int v) { val = v; } }
static class LinkedList {
Node head;
void add(int v) {
Node n = new Node(v);
if (head == null) { head = n; return; }
Node cur = head;
while (cur.next != null) cur = cur.next;
cur.next = n;
}
void delete(int v) {
if (head == null) return;
if (head.val == v) { head = head.next; return; }
Node cur = head;
while (cur.next != null && cur.next.val != v) cur = cur.next;
if (cur.next != null) cur.next = cur.next.next;
}
void print() {
for (Node cur = head; cur != null; cur = cur.next) System.out.print(cur.val + " -> ");
System.out.println("null");
}
}
public static void main(String[] a) {
LinkedList list = new LinkedList();
list.add(1); list.add(2); list.add(3);
list.delete(2);
list.print(); // 1 -> 3 -> null
}
}
Say it aloud: "Node holds value plus next; add walks to the tail, delete relinks around the target."
Q24. Use HashMap to count word frequency in a paragraph¶
Approach: Split on whitespace, tally with merge; a Java 8 stream groupingBy/counting does it in one line. O(n).
import java.util.*;
import java.util.stream.*;
public class Q24 {
static Map<String, Integer> classic(String text) {
Map<String, Integer> map = new HashMap<>();
for (String w : text.toLowerCase().split("\\s+")) map.merge(w, 1, Integer::sum);
return map;
}
static Map<String, Long> stream(String text) {
return Arrays.stream(text.toLowerCase().split("\\s+"))
.collect(Collectors.groupingBy(w -> w, Collectors.counting()));
}
public static void main(String[] a) {
String text = "the cat the dog the bird";
System.out.println(classic(text)); // {the=3, cat=1, dog=1, bird=1} — HashMap: order NOT guaranteed
System.out.println(stream(text)); // same counts; use a LinkedHashMap/TreeMap if you need stable order
}
}
Say it aloud: "Split into words then either merge into a map or groupingBy(w, counting()) in streams."
Q25. Find common elements in two arrays/lists¶
Approach: Put one array in a HashSet, retainAll the other — the intersection remains. O(n+m).
import java.util.*;
import java.util.stream.*;
public class Q25 {
static Set<Integer> common(int[] a, int[] b) {
Set<Integer> setA = Arrays.stream(a).boxed().collect(Collectors.toSet());
Set<Integer> setB = Arrays.stream(b).boxed().collect(Collectors.toSet());
setA.retainAll(setB);
return setA;
}
public static void main(String[] a) {
System.out.println(common(new int[]{1,2,3,4}, new int[]{3,4,5,6})); // [3, 4]
}
}
Say it aloud: "retainAll on one set against the other leaves exactly the intersection."
Q26. Sort a Map by values¶
Approach: Stream the entries, sort by a value Comparator, collect into a LinkedHashMap to keep order. O(n log n).
import java.util.*;
import java.util.stream.*;
public class Q26 {
static <K, V extends Comparable<V>> Map<K, V> sortByValue(Map<K, V> map) {
return map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue,
(a, b) -> a, LinkedHashMap::new));
}
public static void main(String[] a) {
Map<String, Integer> m = new HashMap<>();
m.put("a", 3); m.put("b", 1); m.put("c", 2);
System.out.println(sortByValue(m)); // {b=1, c=2, a=3}
}
}
Say it aloud: "Stream entries, sort with comparingByValue, collect into a LinkedHashMap to preserve the new order."
Q27. Use Java 8 Stream to filter even numbers from a list¶
Approach: stream().filter(n -> n % 2 == 0) then collect. O(n).
import java.util.*;
import java.util.stream.*;
public class Q27 {
static List<Integer> evens(List<Integer> nums) {
return nums.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
}
public static void main(String[] a) {
System.out.println(evens(Arrays.asList(1, 2, 3, 4, 5, 6))); // [2, 4, 6]
}
}
Say it aloud: "A one-line stream: filter on n % 2 == 0 and collect to a list."
Q28. Find the first repeating element in an array¶
Approach: Scan left-to-right; the first value already in a seen-set is the answer. O(n).
import java.util.*;
public class Q28 {
static Integer firstRepeating(int[] arr) {
Set<Integer> seen = new HashSet<>();
for (int x : arr) {
if (!seen.add(x)) return x; // add fails => already seen
}
return null;
}
public static void main(String[] a) {
System.out.println(firstRepeating(new int[]{3, 1, 4, 1, 5, 3})); // 1
}
}
Say it aloud: "First element whose set.add returns false is the first repeat encountered."
Q29. Find missing number in a sequence (e.g., 1 to 100)¶
Approach: Expected sum is n(n+1)/2; subtract the actual sum to get the missing value. O(n), O(1) space.
public class Q29 {
static int findMissing(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[] a) {
// 1..10 missing 7
System.out.println(findMissing(new int[]{1,2,3,4,5,6,8,9,10}, 10)); // 7
}
}
Say it aloud: "Gauss's sum n(n+1)/2 minus the actual sum is exactly the missing number."
Q30. Detect a cycle in a LinkedList¶
Approach: Floyd's tortoise-and-hare — slow moves 1, fast moves 2; they meet iff there is a cycle. O(n) time, O(1) space.
public class Q30 {
static class Node { int val; Node next; Node(int v) { val = v; } }
static boolean hasCycle(Node head) {
Node slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}
public static void main(String[] a) {
Node n1 = new Node(1), n2 = new Node(2), n3 = new Node(3);
n1.next = n2; n2.next = n3; n3.next = n1; // cycle back to n1
System.out.println(hasCycle(n1)); // true
}
}
Say it aloud: "Fast moves twice as quick as slow; inside a loop it laps slow and they collide."