From 5332aebbbebe480caba76798a02fa9ab480a7d7d Mon Sep 17 00:00:00 2001 From: sabarirajan83 Date: Mon, 11 May 2026 21:48:30 +0530 Subject: [PATCH 1/2] feat: add NearestElement stack algorithms and fix Javadoc warnings Fixed 'documentation comment is not attached to any declaration' errors in: - AnyBaseToAnyBase.java - InterpolationSearch.java - LinearSearch.java These changes ensure build compatibility with modern JDK versions. --- .../conversions/AnyBaseToAnyBase.java | 14 +- .../datastructures/stacks/NearestElement.java | 130 ++++++++++++++++++ .../searches/InterpolationSearch.java | 11 -- .../thealgorithms/searches/LinearSearch.java | 13 -- .../stacks/NearestElementTest.java | 110 +++++++++++++++ 5 files changed, 246 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java create mode 100644 src/test/java/com/thealgorithms/datastructures/stacks/NearestElementTest.java diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java index 3d31cb3e7f6c..8d54a9660b7e 100644 --- a/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java +++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java @@ -1,10 +1,3 @@ -/** - * [Brief description of what the algorithm does] - *

- * Time Complexity: O(n) [or appropriate complexity] - * Space Complexity: O(n) - * @author Reshma Kakkirala - */ package com.thealgorithms.conversions; import java.util.Arrays; @@ -16,8 +9,13 @@ * Class for converting from "any" base to "any" other base, when "any" means * from 2-36. Works by going from base 1 to decimal to base 2. Includes * auxiliary method for determining whether a number is valid for a given base. - * + + * [Brief description of what the algorithm does] + *

+ * Time Complexity: O(n) [or appropriate complexity] + * Space Complexity: O(n) * @author Michael Rolland + * @author Reshma Kakkirala * @version 2017.10.10 */ public final class AnyBaseToAnyBase { diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java b/src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java new file mode 100644 index 000000000000..5616b1bfdce3 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java @@ -0,0 +1,130 @@ +package com.thealgorithms.datastructures.stacks; + +import java.util.Stack; + +/** + * The NearestElement class provides implementations for classic stack-based + * algorithms to find the nearest greater or smaller elements in an array. These + * algorithms use a Monotonic Stack approach to achieve linear time complexity. + */ +public final class NearestElement { + + private NearestElement() { + } + + /** + * For each element in an array, finds the first element to its right that + * is greater. + * + * @param arr the input array of integers + * @return an array where each index i contains the nearest greater element + * to the right of arr[i], or -1 if none exists + * @throws IllegalArgumentException if the input array is null + */ + public static int[] nearestGreaterToRight(int[] arr) { + if (arr == null) { + throw new IllegalArgumentException("Input array cannot be null"); + } + int n = arr.length; + int[] result = new int[n]; + Stack stack = new Stack<>(); + + for (int i = n - 1; i >= 0; i--) { + // Safety Check 1: Short-circuit && prevents peek() on empty stack + while (!stack.isEmpty() && stack.peek() <= arr[i]) { + stack.pop(); + } + // Safety Check 2: Ternary operator handles empty stack case + result[i] = stack.isEmpty() ? -1 : stack.peek(); + stack.push(arr[i]); + } + return result; + } + + /** + * For each element in an array, finds the first element to its left that is + * greater. + * + * @param arr the input array of integers + * @return an array where each index i contains the nearest greater element + * to the left of arr[i], or -1 if none exists + * @throws IllegalArgumentException if the input array is null + */ + public static int[] nearestGreaterToLeft(int[] arr) { + if (arr == null) { + throw new IllegalArgumentException("Input array cannot be null"); + } + int n = arr.length; + int[] result = new int[n]; + Stack stack = new Stack<>(); + + for (int i = 0; i < n; i++) { + // Safety Check 3: Short-circuit && prevents peek() on empty stack + while (!stack.isEmpty() && stack.peek() <= arr[i]) { + stack.pop(); + } + // Safety Check 4: Ternary operator handles empty stack case + result[i] = stack.isEmpty() ? -1 : stack.peek(); + stack.push(arr[i]); + } + return result; + } + + /** + * For each element in an array, finds the first element to its right that + * is smaller. + * + * @param arr the input array of integers + * @return an array where each index i contains the nearest smaller element + * to the right of arr[i], or -1 if none exists + * @throws IllegalArgumentException if the input array is null + */ + public static int[] nearestSmallerToRight(int[] arr) { + if (arr == null) { + throw new IllegalArgumentException("Input array cannot be null"); + } + int n = arr.length; + int[] result = new int[n]; + Stack stack = new Stack<>(); + + for (int i = n - 1; i >= 0; i--) { + // Safety Check 5: Short-circuit && prevents peek() on empty stack + while (!stack.isEmpty() && stack.peek() >= arr[i]) { + stack.pop(); + } + // Safety Check 6: Ternary operator handles empty stack case + result[i] = stack.isEmpty() ? -1 : stack.peek(); + stack.push(arr[i]); + } + return result; + } + + /** + * For each element in an array, finds the first element to its left that is + * smaller. + * + * @param arr the input array of integers + * @return an array where each index i contains the nearest smaller element + * to the left of arr[i], or -1 if none exists + * @throws IllegalArgumentException if the input array is null + */ + public static int[] nearestSmallerToLeft(int[] arr) { + if (arr == null) { + throw new IllegalArgumentException("Input array cannot be null"); + } + int n = arr.length; + int[] result = new int[n]; + Stack stack = new Stack<>(); + + for (int i = 0; i < n; i++) { + // Safety Check 7: Short-circuit && prevents peek() on empty stack + while (!stack.isEmpty() && stack.peek() >= arr[i]) { + stack.pop(); + } + // Safety Check 8: Ternary operator handles empty stack case + result[i] = stack.isEmpty() ? -1 : stack.peek(); + stack.push(arr[i]); + } + return result; + } +} diff --git a/src/main/java/com/thealgorithms/searches/InterpolationSearch.java b/src/main/java/com/thealgorithms/searches/InterpolationSearch.java index d24cc1c774bc..3ac6be25bf53 100644 --- a/src/main/java/com/thealgorithms/searches/InterpolationSearch.java +++ b/src/main/java/com/thealgorithms/searches/InterpolationSearch.java @@ -1,14 +1,3 @@ -/** - * Interpolation Search estimates the position of the target value - * based on the distribution of values. - * - * Example: - * Input: [10, 20, 30, 40], target = 30 - * Output: Index = 2 - * - * Time Complexity: O(log log n) (average case) - * Space Complexity: O(1) - */ package com.thealgorithms.searches; /** diff --git a/src/main/java/com/thealgorithms/searches/LinearSearch.java b/src/main/java/com/thealgorithms/searches/LinearSearch.java index 3f273e167f0a..920a2c3aef31 100644 --- a/src/main/java/com/thealgorithms/searches/LinearSearch.java +++ b/src/main/java/com/thealgorithms/searches/LinearSearch.java @@ -1,16 +1,3 @@ -/** - * Performs Linear Search on an array. - * - * Linear search checks each element one by one until the target is found - * or the array ends. - * - * Example: - * Input: [2, 4, 6, 8], target = 6 - * Output: Index = 2 - * - * Time Complexity: O(n) - * Space Complexity: O(1) - */ package com.thealgorithms.searches; import com.thealgorithms.devutils.searches.SearchAlgorithm; diff --git a/src/test/java/com/thealgorithms/datastructures/stacks/NearestElementTest.java b/src/test/java/com/thealgorithms/datastructures/stacks/NearestElementTest.java new file mode 100644 index 000000000000..e702e481b63a --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/stacks/NearestElementTest.java @@ -0,0 +1,110 @@ +package com.thealgorithms.datastructures.stacks; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; + +/** + * Comprehensive JUnit 5 tests for NearestElement algorithms. + * These tests cover standard cases, edge cases, negative numbers, and exceptions. + */ +public class NearestElementTest { + + // --- Standard Test Cases --- + + @Test + void testStandardInput() { + int[] input = {4, 5, 2, 10, 8}; + + // Nearest Greater to Right: For 4->5, 5->10, 2->10, 10->none, 8->none + assertArrayEquals(new int[]{5, 10, 10, -1, -1}, NearestElement.nearestGreaterToRight(input)); + + // Nearest Greater to Left: For 4->none, 5->none, 2->5, 10->none, 8->10 + assertArrayEquals(new int[]{-1, -1, 5, -1, 10}, NearestElement.nearestGreaterToLeft(input)); + + // Nearest Smaller to Right: For 4->2, 5->2, 2->none, 10->8, 8->none + assertArrayEquals(new int[]{2, 2, -1, 8, -1}, NearestElement.nearestSmallerToRight(input)); + + // Nearest Smaller to Left: For 4->none, 5->4, 2->none, 10->2, 8->2 + assertArrayEquals(new int[]{-1, 4, -1, 2, 2}, NearestElement.nearestSmallerToLeft(input)); + } + + // --- Edge Cases: Empty and Single Element --- + + @Test + void testEmptyArray() { + int[] input = {}; + int[] expected = {}; + // An empty array should return an empty array for all variations[cite: 1065]. + assertArrayEquals(expected, NearestElement.nearestGreaterToRight(input)); + assertArrayEquals(expected, NearestElement.nearestSmallerToLeft(input)); + } + + @Test + void testSingleElementArray() { + int[] input = {10}; + int[] expected = {-1}; + // A single element has no neighbors, so it should always return the sentinel -1. + assertArrayEquals(expected, NearestElement.nearestGreaterToRight(input)); + assertArrayEquals(expected, NearestElement.nearestSmallerToLeft(input)); + } + + // --- Edge Cases: Uniform and Monotonic Sequences --- + + @Test + void testAllIdenticalElements() { + int[] input = {5, 5, 5, 5}; + int[] expected = {-1, -1, -1, -1}; + // Since elements are equal, none are strictly greater or smaller. + assertArrayEquals(expected, NearestElement.nearestGreaterToRight(input)); + assertArrayEquals(expected, NearestElement.nearestSmallerToRight(input)); + } + + @Test + void testStrictlyIncreasing() { + int[] input = {1, 2, 3, 4}; + // Greater to Right: each element has a successor + assertArrayEquals(new int[]{2, 3, 4, -1}, NearestElement.nearestGreaterToRight(input)); + // Smaller to Right: no element has a smaller value to its right + assertArrayEquals(new int[]{-1, -1, -1, -1}, NearestElement.nearestSmallerToRight(input)); + } + + @Test + void testStrictlyDecreasing() { + int[] input = {4, 3, 2, 1}; + // Smaller to Right: each element has a smaller successor + assertArrayEquals(new int[]{3, 2, 1, -1}, NearestElement.nearestSmallerToRight(input)); + // Greater to Right: no element has a larger value to its right + assertArrayEquals(new int[]{-1, -1, -1, -1}, NearestElement.nearestGreaterToRight(input)); + } + + // --- Negative Numbers and Large Values --- + + @Test + void testNegativeNumbers() { + int[] input = {-10, -5, -2, -8}; + // Nearest Greater to Right: -10 -> -5, -5 -> -2, -2 -> none, -8 -> none + assertArrayEquals(new int[]{-5, -2, -1, -1}, NearestElement.nearestGreaterToRight(input)); + // Nearest Smaller to Left: -10 -> none, -5 -> -10, -2 -> -5, -8 -> -10 + assertArrayEquals(new int[]{-1, -10, -5, -10}, NearestElement.nearestSmallerToLeft(input)); + } + + @Test + void testExtremeValues() { + int[] input = {Integer.MAX_VALUE, 0, Integer.MIN_VALUE}; + // Smaller to Right: MAX -> 0, 0 -> MIN, MIN -> none + assertArrayEquals(new int[]{0, Integer.MIN_VALUE, -1}, NearestElement.nearestSmallerToRight(input)); + // Greater to Left: MAX -> none, 0 -> MAX, MIN -> 0 + assertArrayEquals(new int[]{-1, Integer.MAX_VALUE, 0}, NearestElement.nearestGreaterToLeft(input)); + } + + // --- Exception Handling --- + + @Test + void testNullInput() { + // Verifies that an IllegalArgumentException is thrown for null input[cite: 1065, 1068]. + assertThrows(IllegalArgumentException.class, () -> { + NearestElement.nearestGreaterToRight(null); + }); + } +} \ No newline at end of file From d732a67163ac90d2d1e9fec75facc3f3f113b765 Mon Sep 17 00:00:00 2001 From: sabarirajan83 Date: Tue, 26 May 2026 12:53:36 +0530 Subject: [PATCH 2/2] wikipedia url added for NearestElement program --- .../com/thealgorithms/datastructures/stacks/NearestElement.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java b/src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java index 5616b1bfdce3..733ea5a6a36a 100644 --- a/src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/NearestElement.java @@ -6,6 +6,8 @@ * The NearestElement class provides implementations for classic stack-based * algorithms to find the nearest greater or smaller elements in an array. These * algorithms use a Monotonic Stack approach to achieve linear time complexity. + * For more details, see: + * https://en.wikipedia.org/wiki/All-nearest-smaller-values */ public final class NearestElement {