Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
/**
* [Brief description of what the algorithm does]
* <p>
* Time Complexity: O(n) [or appropriate complexity]
* Space Complexity: O(n)
* @author Reshma Kakkirala
*/
package com.thealgorithms.conversions;

import java.util.Arrays;
Expand All @@ -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]
* <p>
* 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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
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.
* For more details, see:
* https://en.wikipedia.org/wiki/All-nearest-smaller-values
*/
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<Integer> stack = new Stack<>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using ArrayDeque instead of Stack class,
it is faster and recommended in Java docs.

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<Integer> 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<Integer> 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<Integer> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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;

/**
Expand Down
13 changes: 0 additions & 13 deletions src/main/java/com/thealgorithms/searches/LinearSearch.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great test coverage for null input edge case!

// Verifies that an IllegalArgumentException is thrown for null input[cite: 1065, 1068].
assertThrows(IllegalArgumentException.class, () -> {
NearestElement.nearestGreaterToRight(null);
});
}
}