Solving Array, String, and Number-Based Coding Challenges in Java
Course: Core Java Training
Topic: Solving Array, String, and Number-Based Coding Challenges
Course Link: Core Java Training at JustAcademy
Demo Link: Register for a Free Course Demo
Website: JustAcademy
1. Introduction
Solving array, string, and number-based coding challenges is an important part of learning Core Java. These problems help developers improve logical thinking, understand loops and conditional statements, use methods effectively, and write efficient programs.
Array challenges focus on processing collections of values, string challenges involve manipulating and analysing text, and number-based challenges use mathematical operations to solve computational problems. These techniques are frequently useful in programming assignments, technical interviews, competitive programming, and real-world application development.
The objective is not simply to produce the correct output. A good solution should also be readable, reliable, efficient, and capable of handling edge cases.
2. Learning Objectives
- Understand common array, string, and number-based problems.
- Use loops, conditional statements, operators, and methods to solve challenges.
- Find minimum, maximum, and second-largest array elements.
- Reverse strings and arrays and identify palindromes.
- Count character frequencies and check anagrams.
- Calculate factorials, Fibonacci numbers, prime numbers, and Armstrong numbers.
- Understand time complexity and space complexity.
- Test solutions against normal, boundary, and invalid inputs.
3. Understanding the Problem-Solving Process
Before writing Java code, understand what the problem asks you to calculate or return. Carefully identify the input, expected output, constraints, and special cases.
- Understand the problem: Identify the information provided and the required result.
- Work through an example: Solve a small example manually.
- Choose an approach: Decide whether to use iteration, sorting, two pointers, a frequency array, or mathematical calculations.
- Write pseudocode: Express the logic in simple steps.
- Implement the solution: Translate the steps into Java.
- Test edge cases: Check empty inputs, duplicate values, negative numbers, and boundary values where relevant.
- Evaluate efficiency: Estimate execution time and additional memory usage.
Example of pseudocode
START
Read an array
Set maximum to the first element
For each remaining element:
If element is greater than maximum:
Update maximum
Display maximum
END
4. Array-Based Coding Challenges
4.1 What Is an Array?
An array is an object that stores a fixed number of elements of the same type. Each element is accessed through an index, starting at zero. Java provides the java.util.Arrays utility class for operations such as sorting and displaying array contents.
int[] numbers = {12, 25, 8, 40, 16};
System.out.println(numbers[0]); // 12
System.out.println(numbers[3]); // 40
System.out.println(numbers.length); // 5
Array indices range from 0 to numbers.length - 1. Accessing an invalid index causes an ArrayIndexOutOfBoundsException.
4.2 Find the Largest and Smallest Elements
Problem: Find the largest and smallest values in an integer array without sorting it.
Approach: Assume the first element is both the minimum and maximum. Compare each subsequent element and update the appropriate variable.
public class ArrayMinMax {
public static void main(String[] args) {
int[] numbers = {12, 5, 28, 3, 19};
if (numbers.length == 0) {
System.out.println("Array is empty");
return;
}
int min = numbers[0];
int max = numbers[0];
for (int number : numbers) {
if (number < min) {
min = number;
}
if (number > max) {
max = number;
}
}
System.out.println("Minimum: " + min);
System.out.println("Maximum: " + max);
}
}
Output:
Minimum: 3
Maximum: 28
Complexity: Time O(n), auxiliary space O(1). Each element is examined once.
4.3 Find the Second-Largest Distinct Element
Problem: Find the second-largest distinct value. For example, in {10, 25, 25, 18}, the answer is 18, not 25.
public class SecondLargest {
public static void main(String[] args) {
int[] numbers = {10, 25, 25, 18, 7};
Integer largest = null;
Integer second = null;
for (int number : numbers) {
if (largest == null || number > largest) {
if (largest == null || number != largest) {
second = largest;
largest = number;
}
} else if (number != largest &&
(second == null || number > second)) {
second = number;
}
}
if (second == null) {
System.out.println("No second-largest distinct value");
} else {
System.out.println("Second largest: " + second);
}
}
}
Output:
Second largest: 18
Explanation: The algorithm tracks the largest and second-largest distinct values while traversing the array. It handles duplicate maximum values and reports when there is no second distinct value.
Complexity: Time O(n), auxiliary space O(1).
4.4 Reverse an Array
Reversing an array places its last element first and its first element last. A two-pointer approach performs this operation in place.
import java.util.Arrays;
public class ReverseArray {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
int left = 0;
int right = numbers.length - 1;
while (left < right) {
int temp = numbers[left];
numbers[left] = numbers[right];
numbers[right] = temp;
left++;
right--;
}
System.out.println(Arrays.toString(numbers));
}
}
Output:
[5, 4, 3, 2, 1]
Complexity: Time O(n), auxiliary space O(1). The two pointers move towards the centre, swapping elements along the way.
4.5 Calculate the Sum of Array Elements
Problem: Add all elements of an integer array.
public class ArraySum {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40};
long sum = 0;
for (int number : numbers) {
sum += number;
}
System.out.println("Sum: " + sum);
}
}
Output: Sum: 100
Complexity: Time O(n), auxiliary space O(1). Using long allows a larger result than int, although even long can overflow for sufficiently large totals.
4.6 Search for an Element
Linear search checks each element until it finds the target or reaches the end of the array.
public class LinearSearch {
public static void main(String[] args) {
int[] numbers = {4, 8, 15, 16, 23, 42};
int target = 16;
int index = -1;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == target) {
index = i;
break;
}
}
System.out.println("Index: " + index);
}
}
Output: Index: 3
Complexity: Worst-case time O(n), auxiliary space O(1). Linear search works even when the array is unsorted.
4.7 Sort an Array
Java's Arrays.sort() method sorts a primitive integer array into ascending numerical order.
import java.util.Arrays;
public class SortArray {
public static void main(String[] args) {
int[] numbers = {9, 2, 7, 1, 5};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
Output: [1, 2, 5, 7, 9]
For primitive arrays, sorting is typically O(n log n). If the original order must be preserved, create a copy before sorting because Arrays.sort() changes the supplied array.
4.8 Count the Frequency of Each Element
Frequency counting identifies how often each value occurs. A map is useful when the possible values are not restricted to a small range.
import java.util.LinkedHashMap;
import java.util.Map;
public class ArrayFrequency {
public static void main(String[] args) {
int[] numbers = {2, 4, 2, 5, 4, 2};
Map<Integer, Integer> frequency = new LinkedHashMap<>();
for (int number : numbers) {
frequency.put(
number,
frequency.getOrDefault(number, 0) + 1
);
}
System.out.println(frequency);
}
}
Output: {2=3, 4=2, 5=1}
Complexity: Expected time O(n) with typical hash-map operations and O(k) additional space, where k is the number of distinct values.
5. String-Based Coding Challenges
5.1 Understanding Strings in Java
A String represents a sequence of characters. Java strings are immutable, meaning that operations such as concatenation create a new string rather than changing the original object. Use StringBuilder when repeatedly constructing or modifying text.
String language = "Java";
System.out.println(language.length()); // 4
System.out.println(language.charAt(0)); // J
System.out.println(language.substring(1)); // ava
5.2 Reverse a String
Problem: Reverse the characters in a string.
public class ReverseString {
public static void main(String[] args) {
String text = "Java";
String reversed = new StringBuilder(text).reverse().toString();
System.out.println(reversed);
}
}
Output: avaJ
Complexity: Time O(n), additional space O(n) for the reversed result.
Important: This is suitable for many basic character-reversal problems. Some Unicode characters are represented by multiple UTF-16 code units, so reversing arbitrary Unicode text may require code-point-aware processing.
5.3 Check Whether a String Is a Palindrome
A palindrome reads the same forward and backward. Examples include level, madam, and 121.
public class StringPalindrome {
public static void main(String[] args) {
String text = "Madam";
String normalized = text.toLowerCase();
int left = 0;
int right = normalized.length() - 1;
boolean palindrome = true;
while (left < right) {
if (normalized.charAt(left) != normalized.charAt(right)) {
palindrome = false;
break;
}
left++;
right--;
}
System.out.println("Palindrome: " + palindrome);
}
}
Output: Palindrome: true
Complexity: Time O(n), auxiliary space O(1) beyond the normalized string. This example ignores case but does not ignore spaces or punctuation.
5.4 Count Vowels and Consonants
This challenge counts English alphabetic vowels and consonants. Characters other than letters, including digits, spaces, and punctuation, are ignored.
public class VowelConsonantCount {
public static void main(String[] args) {
String text = "Core Java";
int vowels = 0;
int consonants = 0;
for (char ch : text.toLowerCase().toCharArray()) {
if (ch >= 'a' && ch <= 'z') {
if ("aeiou".indexOf(ch) >= 0) {
vowels++;
} else {
consonants++;
}
}
}
System.out.println("Vowels: " + vowels);
System.out.println("Consonants: " + consonants);
}
}
Output:
Vowels: 4
Consonants: 4
5.5 Check Whether Two Strings Are Anagrams
Anagrams contain the same characters with the same frequencies, although the character order may differ. For example, listen and silent are anagrams.
import java.util.Arrays;
public class AnagramCheck {
public static void main(String[] args) {
String first = "listen";
String second = "silent";
char[] a = first.toLowerCase().toCharArray();
char[] b = second.toLowerCase().toCharArray();
Arrays.sort(a);
Arrays.sort(b);
boolean result = Arrays.equals(a, b);
System.out.println("Anagrams: " + result);
}
}
Output: Anagrams: true
Complexity: Time O(n log n) for sorting, assuming both strings have length n. This implementation compares characters after converting to lowercase; it does not remove spaces or punctuation.
5.6 Count Character Occurrences
A character-frequency map can help find repeated characters or the first non-repeating character.
import java.util.LinkedHashMap;
import java.util.Map;
public class CharacterFrequency {
public static void main(String[] args) {
String text = "programming";
Map<Character, Integer> counts = new LinkedHashMap<>();
for (char ch : text.toCharArray()) {
counts.put(ch, counts.getOrDefault(ch, 0) + 1);
}
System.out.println(counts);
}
}
Output:
{p=1, r=2, o=1, g=2, a=1, m=2, i=1, n=1}
Complexity: Expected time O(n), with O(k) additional space for k distinct characters.
5.7 Check Whether a String Contains Only Digits
For a non-empty string containing only ASCII digits, every character must fall between '0' and '9'. An empty string should be handled separately because it contains no characters to test.
public class DigitStringCheck {
public static void main(String[] args) {
String value = "202610";
boolean onlyDigits = !value.isEmpty();
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
if (ch < '0' || ch > '9') {
onlyDigits = false;
break;
}
}
System.out.println("Only digits: " + onlyDigits);
}
}
Output: Only digits: true
6. Number-Based Coding Challenges
6.1 Check Whether a Number Is Prime
A prime number is an integer greater than 1 that has exactly two positive divisors: 1 and itself. Numbers less than 2 are not prime.
public class PrimeCheck {
public static void main(String[] args) {
int number = 29;
boolean prime = number >= 2;
for (int i = 2; prime && i <= number / i; i++) {
if (number % i == 0) {
prime = false;
}
}
System.out.println("Prime: " + prime);
}
}
Output: Prime: true
Explanation: It is enough to test possible divisors up to the square root of the number. The condition i <= number / i avoids the multiplication overflow risk of checking i * i <= number.
Complexity: Worst-case time O(√n), auxiliary space O(1).
6.2 Calculate the Factorial of a Number
The factorial of a non-negative integer n, written n!, is the product of all positive integers from 1 to n. By definition, 0! equals 1.
public class Factorial {
public static void main(String[] args) {
int number = 5;
if (number < 0) {
System.out.println("Factorial is not defined for negative integers");
return;
}
long factorial = 1;
for (int i = 2; i <= number; i++) {
factorial *= i;
}
System.out.println("Factorial: " + factorial);
}
}
Output: Factorial: 120
Complexity: Time O(n), auxiliary space O(1). A Java long can represent factorials only up to 20! without overflow. For larger values, consider BigInteger.
6.3 Generate the Fibonacci Sequence
The Fibonacci sequence starts with 0 and 1. Each subsequent term is the sum of the previous two terms: 0, 1, 1, 2, 3, 5, 8, and so on.
public class Fibonacci {
public static void main(String[] args) {
int terms = 8;
long first = 0;
long second = 1;
for (int i = 0; i < terms; i++) {
System.out.print(first);
if (i < terms - 1) {
System.out.print(" ");
}
long next = first + second;
first = second;
second = next;
}
}
}
Output: 0 1 1 2 3 5 8 13
Complexity: Time O(n), auxiliary space O(1). The numeric values eventually exceed the range of long for sufficiently large terms.
6.4 Find the Sum of Digits
For example, the sum of the digits of 572 is 5 + 7 + 2 = 14. The remainder operator extracts the final digit, and integer division removes it.
public class SumOfDigits {
public static void main(String[] args) {
long number = -572;
long remaining = Math.abs(number);
int sum = 0;
while (remaining > 0) {
sum += remaining % 10;
remaining /= 10;
}
System.out.println("Sum of digits: " + sum);
}
}
Output: Sum of digits: 14
Important: Math.abs(Long.MIN_VALUE) remains negative because its positive magnitude cannot be represented by a long. For fully robust handling of every long value, use a BigInteger or explicitly handle that boundary case.
6.5 Check Whether a Number Is an Armstrong Number
An Armstrong number is a non-negative integer equal to the sum of each of its digits raised to the number of digits. For example, 153 is an Armstrong number because 1³ + 5³ + 3³ = 153.
public class ArmstrongNumber {
public static void main(String[] args) {
int number = 153;
if (number < 0) {
System.out.println("Not an Armstrong number");
return;
}
int digits = String.valueOf(number).length();
int remaining = number;
long sum = 0;
do {
int digit = remaining % 10;
long power = 1;
for (int i = 0; i < digits; i++) {
power *= digit;
}
sum += power;
remaining /= 10;
} while (remaining > 0);
System.out.println("Armstrong: " + (sum == number));
}
}
Output: Armstrong: true
The do-while loop also handles zero correctly: zero is an Armstrong number. For very large inputs, use an appropriate numeric type and account for possible overflow.
6.6 Reverse an Integer
Reversing a number rearranges its decimal digits. For example, 1234 becomes 4321. Be careful with negative inputs and overflow.
public class ReverseNumber {
public static void main(String[] args) {
int number = 1234;
int remaining = number;
long reversed = 0;
while (remaining != 0) {
int digit = remaining % 10;
reversed = reversed * 10 + digit;
remaining /= 10;
}
System.out.println("Reversed: " + reversed);
}
}
Output: Reversed: 4321
Complexity: Time O(d), auxiliary space O(1), where d is the number of decimal digits. Using long prevents many intermediate overflows for an int input, but the result's type and the desired handling of negative numbers should still be defined explicitly.
6.7 Find the Greatest Common Divisor (GCD)
The greatest common divisor of two integers is the largest positive integer that divides both. The Euclidean algorithm repeatedly replaces the pair with the second number and the remainder.
public class GCDExample {
public static void main(String[] args) {
int a = 48;
int b = 18;
while (b != 0) {
int remainder = a % b;
a = b;
b = remainder;
}
System.out.println("GCD: " + Math.abs(a));
}
}
Output: GCD: 6
Complexity: O(log(min(a, b))) for non-negative inputs, excluding the special case where both inputs are zero. A production implementation should define how it handles zero and the minimum representable integer.
7. Common Problem-Solving Techniques
| Technique |
Purpose |
Example |
| Single traversal |
Process each element once |
Find minimum and maximum |
| Two pointers |
Process data from two positions |
Reverse an array or check a palindrome |
| Sorting |
Arrange values into a useful order |
Sort an array or compare anagrams |
| Hash map |
Store frequencies or associations |
Count repeated values or characters |
| Mathematical iteration |
Use arithmetic properties |
Factorial, digit sum, and GCD |
| Early termination |
Stop when the result is known |
Linear search or prime checking |
8. Time and Space Complexity
Time complexity describes how the number of operations grows with input size. Space complexity describes memory usage. Understanding both helps you compare possible solutions.
| Complexity |
Meaning |
Example |
| O(1) |
Constant work |
Access an array element by index |
| O(log n) |
Work grows logarithmically |
Binary search on sorted data |
| O(n) |
Work grows linearly |
Find an array maximum |
| O(n log n) |
Common efficient sorting scale |
Many comparison-sorting algorithms |
| O(n²) |
Work grows quadratically |
Compare every pair using nested loops |
For example, a nested loop that compares every element with every other element usually takes O(n²) time. If a problem can be solved with a single traversal and a few variables, that approach may be much more efficient.
9. Common Mistakes and How to Avoid Them
- Ignoring empty arrays: Check the array length before reading the first element.
- Using the wrong index boundary: The last valid array index is
length - 1.
- Confusing == and equals(): Use
equals() to compare string content, not object references.
- Overlooking duplicate values: Decide whether a problem requires distinct values, especially when finding the second-largest element.
- Integer overflow: Consider
long or BigInteger for calculations that exceed int limits.
- Incorrect handling of zero and negative numbers: Define expected behaviour for factorial, digit operations, primes, and GCD.
- Unnecessary repeated string concatenation: Use
StringBuilder when building a string in a loop.
- Testing only one input: Include edge cases and boundary values.
- Writing code before understanding the task: Verify the required output and constraints first.
10. Practice Exercises
Beginner Level
- Find the sum and average of all values in an array.
- Count how many even and odd numbers are present in an array.
- Reverse an array without using another array.
- Count vowels in a string.
- Check whether a given string is a palindrome.
- Calculate the factorial of a non-negative integer.
- Print the first n Fibonacci numbers.
- Find the sum of the digits of a positive integer.
Intermediate Level
- Find the second-largest distinct value in an array.
- Remove duplicate values from an array while preserving their first-occurrence order.
- Find the missing number from a sequence containing values from 1 to n, with exactly one missing value.
- Check whether two strings are anagrams, ignoring spaces and letter case.
- Find the first non-repeating character in a string.
- Check whether a number is an Armstrong number.
- Find the GCD and least common multiple (LCM) of two integers.
- Rotate an array to the left by k positions.
Challenge Level
- Find two array elements whose sum equals a target value.
- Find the longest substring without repeated characters.
- Find the maximum sum of a contiguous subarray.
- Find the most frequent element in an array.
- Check whether one string is a rotation of another.
- Find all prime numbers up to a specified limit.
11. Sample Mini Project: Student Marks Analyzer
This mini project applies array processing, loops, conditional statements, and basic numerical calculations to analyse student marks.
import java.util.Arrays;
public class StudentMarksAnalyzer {
public static void main(String[] args) {
int[] marks = {78, 85, 92, 67, 88};
if (marks.length == 0) {
System.out.println("No marks available");
return;
}
int highest = marks[0];
int lowest = marks[0];
long total = 0;
for (int mark : marks) {
if (mark < 0 || mark > 100) {
System.out.println("Invalid mark: " + mark);
return;
}
total += mark;
highest = Math.max(highest, mark);
lowest = Math.min(lowest, mark);
}
double average = (double) total / marks.length;
Arrays.sort(marks);
System.out.println("Highest: " + highest);
System.out.println("Lowest: " + lowest);
System.out.println("Average: " + average);
System.out.println("Sorted marks: " + Arrays.toString(marks));
}
}
Output:
Highest: 92
Lowest: 67
Average: 82.0
Sorted marks: [67, 78, 85, 88, 92]
Project Extensions
- Count students who passed based on a configurable passing mark.
- Calculate the median score.
- Count how many students received each grade.
- Accept marks through user input using
Scanner.
- Reject invalid inputs and display clear error messages.
12. Core Java Interview Questions and Answers
Q1. What is the difference between an array and an ArrayList?
Answer: An array has a fixed length once created. An ArrayList is a resizable collection that provides methods for adding, removing, and accessing elements. Arrays can store primitive values directly, while an ArrayList uses object types such as Integer for numeric values.
Q2. Why do Java array indices start at zero?
Answer: Zero-based indexing makes the index represent an offset from the beginning of the array. The first element is at offset zero, and the last element is at offset length - 1.
Q3. How do you compare two strings in Java?
Answer: Use equals() to compare string content. Use equalsIgnoreCase() when a case-insensitive comparison is appropriate. The == operator compares object references.
Q4. Why is String immutable?
Answer: String immutability supports safe sharing, predictable behaviour, and reliable use of strings as map keys. Repeated modifications can be handled efficiently with StringBuilder.
Q5. What is the difference between linear search and binary search?
Answer: Linear search checks elements one by one and works on unsorted arrays. Binary search repeatedly halves the search interval and requires sorted data, taking O(log n) time.
Q6. How can you find the second-largest distinct element without sorting?
Answer: Traverse the array once while tracking the largest and second-largest distinct values. This takes O(n) time and O(1) auxiliary space.
Q7. How can you check whether a number is prime efficiently?
Answer: Reject numbers below 2, then test divisors from 2 up to the square root of the number. If none divides it evenly, the number is prime.
Q8. What is the difference between break and continue?
Answer: break terminates the nearest enclosing loop or switch statement. continue skips the remaining statements in the current loop iteration and moves to the next iteration.
Q9. What is time complexity?
Answer: Time complexity describes how an algorithm's computational work grows with input size. It helps compare algorithms independently of a particular machine's execution speed.
Q10. How should you test a coding challenge?
Answer: Test typical inputs, empty inputs where permitted, single-element inputs, duplicates, negative numbers, zero, boundary values, and inputs large enough to reveal performance or overflow problems.
13. Quick Revision Checklist
- Understand array indexing, traversal, sorting, and searching.
- Practise minimum, maximum, sum, frequency, and second-largest problems.
- Use String methods and StringBuilder appropriately.
- Practise string reversal, palindrome checks, character counting, and anagrams.
- Understand prime checking, factorial, Fibonacci, digit sums, Armstrong numbers, and GCD.
- Know when to use loops, two pointers, maps, and sorting.
- Estimate time and auxiliary space complexity.
- Check edge cases, input constraints, and possible numeric overflow.
- Explain the logic clearly before discussing the code.
14. Conclusion
Array, string, and number-based coding challenges form a strong foundation for Core Java programming. By practising these problems regularly, learners develop the ability to break complex tasks into smaller steps, select suitable algorithms, write maintainable code, and reason about performance.
Begin with simple loops and conditions, then move towards frequency maps, two-pointer methods, sorting, and more advanced algorithmic patterns. For every challenge, write the solution, test multiple cases, and explain why the algorithm works.
Explore the JustAcademy Core Java Training course, register for a course demo, or visit the JustAcademy website for more information.