These Java interview exercises cover string processing, arrays, stacks and common search techniques. For each problem, explain the input assumptions, propose an algorithm and state its time and space complexity before writing code. The solutions help compare approaches after you have attempted the problem.
Check empty input, duplicates, negative numbers and overflow where relevant. A correct solution under clear assumptions is more useful in an interview than a short snippet whose edge cases are unexplained.
1. How Do We Solve FizzBuzz?
Write a program that prints the numbers from 1 to 100. But for multiples of 5, print “Fizz” instead of the number, and for multiples of 7, print “Buzz“. For numbers that are multiples of both 5 and 7, print “FizzBuzz.”
Iterate from 1 through 100. Test divisibility by both 5 and 7 first, then each divisor separately, so the combined case is not hidden by an earlier match.
if divisible by both 5 and 7: FizzBuzz
else if divisible by 5: Fizz
else if divisible by 7: Buzz
else: the number
The following Java program demonstrates the usage of the above pseudo steps to solve the FizzBuzz problem using the Stream API. It uses rangeClosed(1, 100) method to iterate over the stream of numbers from 1 to 100. The mapToObj() method checks each number against the algorithm, and the program prints the output.
IntStream.rangeClosed(1, 100)
.mapToObj(i -> i % 5 == 0 ? (i % 7 == 0 ? "FizzBuzz" : "Fizz") : (i % 7 == 0 ? "Buzz" : i))
.forEach(System.out::println);
The program output:
1
2
3
4
Fizz
6
Buzz
...
34
FizzBuzz
36
...
2. How Do We Reverse a String?
Reverse the string without using a ready-made reverse operation. The array-swapping solution below operates on UTF-16 char values; ask whether the interviewer expects supplementary Unicode characters or grapheme clusters to stay intact.
To solve this puzzle, we first convert the string into a character array, and then use two pointers (start and end) to swap characters from the start and end indices iteratively until they meet at the center. It reverses the whole array.
Finally, we convert the reversed character array back into a string and return it as a string.
private static String reverse(String str) {
char[] chars = str.toCharArray();
int start = 0;
int end = chars.length - 1;
while (start < end) {
// Swap characters at start and end indices
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
// Move the indices towards the center
start++;
end--;
}
return new String(chars);
}
Let us test this function with a simple string.
String string = "howtodoinjava";
String reverseString = reverse(string);
System.out.println(reverseString); //avajniodotwoh
3. How Do We Check Whether a String Is a Palindrome?
Write a program to check if a given string is a palindrome (reads the same forward and backward).
A string is a palindrome when its forward and backward forms match under the chosen comparison rules. The example reverses the text and compares it. A two-pointer comparison can avoid allocating the reversed copy.
We already saw a Java program to reverse the string in the previous question. Either we can use the above reverse() function or we can use the built-in Java APIs for a quick example.
String string = "naman";
String reversed = new StringBuilder(string).reverse().toString();
boolean isPalindrome = string.equalsIgnoreCase(reversed); //prints 'true'
The example ignores letter case. Use equals() for a case-sensitive comparison and equalsIgnoreCase() when case should be ignored. Decide separately whether spaces, punctuation and Unicode normalization matter.
4. How Do We Check Whether Two Strings Are Anagrams?
Write a program to check if two given strings are anagrams of each other. An anagram is a word or phrase formed by rearranging the letters of another word or phrase.
We can solve this puzzle in different ways. For example, we can use either of the following approaches.
- We iterate over characters of the first string and remove each character from the second array. At the end, if the second string is empty, both strings contained the same characters, so they are anagrams.
- We sort both strings and compare them. If both strings are equal, it means that the strings are anagrams.
We should check the string’s length. If the lengths of both strings are not equal, the strings are not anagrams.
Let us use the second approach to write the solution.
private static boolean checkAnagrams(String str1, String str2) {
if (str1.length() != str2.length()) {
return false;
}
char[] charArray1 = str1.toCharArray();
char[] charArray2 = str2.toCharArray();
Arrays.sort(charArray1);
Arrays.sort(charArray2);
return Arrays.equals(charArray1, charArray2);
}
Let us test this function with an example.
String str1 = "listen";
String str2 = "silent";
System.out.println(checkAnagrams(str1, str2)); //true
5. How Do We Solve the HiLo Exercise?
The HiLo game has two rules.
- Guess the secret number in a maximum of 7 tries.
- The secret number is an integer between 1 and 100, Inclusive.
After a guess below the secret, the program reports LO; after a higher guess, it reports HI. Use that feedback to narrow the remaining interval. Seven midpoint guesses suffice for an integer from 1 through 100 because each guess removes roughly half of the remaining possibilities.
The following code simulates a player who always guesses the midpoint. The game can give the same LO and HI feedback to a human player.
int secret = 73;
int low = 1;
int high = 100;
int guesses = 0;
while (low <= high) {
int guess = low + (high - low) / 2;
guesses++;
if (guess == secret) break;
if (guess < secret) low = guess + 1; // LO: secret is higher
else high = guess - 1; // HI: secret is lower
}
System.out.println(guesses); // 6
The midpoint rule finds 73 in six guesses for this input. The worst case across the full range takes seven. The complete interactive version is in the HiLo Guessing Game article.
6. How Do We Check Balanced Parentheses?
Write a Java program to check if a given string of parentheses is balanced. For example, “([])” is balanced, but “([)]” is not.
This puzzle can be solved using the Stack data structure. The Stack stores the elements in LIFO order. We can use LIFO feature to match the parentheses.
We iterate over all the characters of the given string, and every time we find an opening parenthesis, we push it onto the stack. When we find a closing parenthesis, we check the last pushed element in the stack, which must be the matching opening parenthesis. For example, '{' will match to '}'.
Accept the expression only if every closer matched the most recent unmatched opener and the stack is empty at the end. Reject a closing bracket when the stack is empty before attempting to pop.
public static boolean checkBalancedParentheses(String expression) {
Stack<Character> stack = new Stack<>();
for (char ch : expression.toCharArray()) {
if (ch == '(' || ch == '{' || ch == '[') {
stack.push(ch);
} else if (ch == ')' || ch == '}' || ch == ']') {
if (stack.isEmpty()) {
return false;
}
char top = stack.pop();
if ((ch == ')' && top != '(') ||
(ch == '}' && top != '{') ||
(ch == ']' && top != '[')) {
return false;
}
}
}
return stack.isEmpty();
}
Let us test the above function with a correct and an incorrectly balanced expression.
String expression1 = "{[ a; ( b; ) c; ]}";
String expression2 = "{[ a; ( b; ) c; }]"; //incorrectly matched in last two characters
checkBalancedParentheses(expression1); //true
checkBalancedParentheses(expression2); //false
7. How Do We Find a Missing Number?
An array contains each integer from 0 through n exactly once except one. Its length is therefore n. Find the missing value without sorting the array.
static int missing(int[] values) {
long n = values.length;
long expected = n * (n + 1) / 2;
long actual = 0;
for (int value : values) actual += value;
return (int) (expected - actual);
}
System.out.println(missing(new int[] {3, 0, 1})); // 2
The expected sum is 0 + 1 + … + n. Subtracting the actual sum leaves the missing value. Use long for the intermediate sum to avoid int overflow. The result assumes the input meets the stated range and uniqueness rules; validate those separately if the caller can provide arbitrary data. The scan takes O(n) time and O(1) extra space.
8. How Do We Find Duplicates in an Array?
Return each repeated integer once, in the order its second occurrence appears. Two sets are enough: one tracks values already seen, and the other collects duplicates.
static Set<Integer> duplicates(int[] values) {
Set<Integer> seen = new HashSet<>();
Set<Integer> repeated = new LinkedHashSet<>();
for (int value : values) {
if (!seen.add(value)) repeated.add(value);
}
return repeated;
}
System.out.println(duplicates(new int[] {1, 2, 3, 2, 3, 3})); // [2, 3]
HashSet.add() returns false when the value is already present. LinkedHashSet retains the order of duplicate discovery. This takes expected O(n) time and O(n) extra space.
9. How Do We Solve Two Sum?
Given an unsorted integer array and a target, return the indices of two distinct elements whose sum is the target. Store each value’s index after checking whether its complement appeared earlier.
static int[] twoSum(int[] values, int target) {
Map<Integer, Integer> indexByValue = new HashMap<>();
for (int i = 0; i < values.length; i++) {
long complement = (long) target - values[i];
if (complement >= Integer.MIN_VALUE && complement <= Integer.MAX_VALUE) {
Integer previous = indexByValue.get((int) complement);
if (previous != null) return new int[] {previous, i};
}
indexByValue.putIfAbsent(values[i], i);
}
return new int[0];
}
System.out.println(Arrays.toString(twoSum(new int[] {2, 7, 11}, 9))); // [0, 1]
Checking before insertion prevents one array element from matching itself. The long subtraction avoids overflow before the map lookup. The scan takes expected O(n) time and O(n) space.
10. How Do We Find the Largest Array Element?
Write a program to find the largest element in an array of integers.
To find the largest number in an array, we create a variable and initialize it with the first value in the array. Next, we iterate over the array elements and compare each number with the variable. If the number is larger than the variable, we assign the number to the variable.
When the loop finishes, the variable contains the largest value from the array.
public static int findLargestElement(int[] array) {
if (array == null || array.length == 0) {
throw new IllegalArgumentException("Array is empty or null.");
}
int largest = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > largest) {
largest = array[i];
}
}
return largest;
}
Let us test the above function with a simple Java program.
int[] array = {10, 20, 30, 40, 90, 23, 12, 60};
int largest = findLargestElement(array);
System.out.println("The largest element in the array is: " + largest); //Prints 90
11. How Do We Find the Longest Substring Without Repeating Characters?
Given a string, write a Java program to find the length of the longest substring without repeating characters.
We can solve this puzzle using the sliding window approach. It uses two variables left and right to track the start and end index of the substring in the specified argument string. Initially, they can be 0 and 0.
A Set represents the current substring under test. Initially, the set can be empty.
We iterate through the string while expanding the right boundary of the substring. If the current character is already present in the set, it means we have a repeating character and we remove it from the left side of the sliding window and move the left boundary to the right. This process continues until there are no repeating characters in the current substring.
Track the maximum window length throughout the scan and return that maximum. The final window need not be the longest one. Each character enters and leaves the window at most once, giving linear time with a suitable set.
public static int findLongestSubstringLength(String str) {
int maxLength = 0;
int left = 0;
int right = 0;
Set<Character> slidingWindow = new HashSet<>();
while (right < str.length()) {
char currentChar = str.charAt(right);
if (slidingWindow.contains(currentChar)) {
slidingWindow.remove(str.charAt(left));
left++;
} else {
slidingWindow.add(currentChar);
maxLength = Math.max(maxLength, right - left + 1);
right++;
}
}
return maxLength;
}
Let us test the program.
String input = "abcabcbb";
int length = findLongestSubstringLength(input);
System.out.println(length); //3
12. How Do We Find Common Elements in Sorted Arrays?
Return each value that appears in every input array once. An empty group has no common values. The input arrays are sorted, but the solution below needs only set membership; LinkedHashSet retains the first array’s ascending order.
static List<Integer> commonValues(Integer[][] arrays) {
if (arrays == null || arrays.length == 0) return List.of();
Set<Integer> common = new LinkedHashSet<>(Arrays.asList(arrays[0]));
for (int i = 1; i < arrays.length; i++) {
common.retainAll(new HashSet<>(Arrays.asList(arrays[i])));
}
return new ArrayList<>(common);
}
Integer[][] arrays = {{1, 2, 2, 4}, {2, 3, 4}, {2, 4, 4}};
System.out.println(commonValues(arrays)); // [2, 4]
Each intersection removes values missing from the next array. Duplicate occurrences do not create duplicate results. The method assumes each inner array is non-null. Expected running time is linear in the total input size when hash operations are well distributed, with extra space proportional to the distinct values.
13. How Do We Rotate an Array?
Write a Java program to rotate an array of size n by k positions to the right.
To solve this puzzle, we can use the following pseudo-code. An example array shows each step.
Suppose, we have the initial array [1, 2, 3, 4, 5] and we want to rotate it by 2 positions.
Intialize the variables n = array.length (5); and k = 2;
Rotate the complete array -> [5, 4, 3, 2, 1]
Reverse the array from positions 0 to k-1 -> [4, 5, 3, 2, 1]
Reverse the array from positions k to n-1 -> [4, 5, 1, 2, 3]
After the reversals, the array is rotated right by k positions. Reversal is the implementation technique, not the final operation. Normalize k by the array length and decide how to handle an empty array or a negative rotation.
Let us write a Java program for the above pseudo-code.
public static void rotateArray(int[] array, int k) {
if (array == null || array.length == 0) {
return;
}
int n = array.length;
k = Math.floorMod(k, n); // Handles large and negative rotations
reverseArray(array, 0, n - 1); // Reverse the entire array
reverseArray(array, 0, k - 1); // Reverse the first k elements
reverseArray(array, k, n - 1); // Reverse the remaining n-k elements
}
public static void reverseArray(int[] array, int start, int end) {
while (start < end) {
int temp = array[start];
array[start] = array[end];
array[end] = temp;
start++;
end--;
}
}
We can test the logic with the following example.
int[] array = {1, 2, 3, 4, 5};
int k = 2;
System.out.println("Original Array: " + Arrays.toString(array));
rotateArray(array, k);
System.out.println("Rotated Array: " + Arrays.toString(array));
Expected output:
Original Array: [1, 2, 3, 4, 5]
Rotated Array: [4, 5, 1, 2, 3]
Happy Learning!