Advertisement
Home Data Structure Arrays Check if an Array is Sorted in Ascending or Descending Order

Check if an Array is Sorted in Ascending or Descending Order

3
Advertisement

Title: Check if an Array is Sorted in Ascending or Descending Order

In this guide, you’ll learn how to check whether a given array is sorted in ascending order, descending order, or not sorted at all. This is a classic array-traversal problem that shows up often in coding interviews, since it tests whether you can reason about array state without extra space.

Understanding the Problem

Given an array of integers, you need to determine its sort order by comparing each element only with its immediate predecessor. An array of size 0 or 1 is trivially considered sorted. For arrays with at least two elements, you’ll walk through the array once per direction and report the first direction that holds true for every pair.

The approach below avoids sorting the array again, which would cost O(n log n). Instead, it uses a single linear pass per direction, giving an overall O(n) time solution.

Approach

The algorithm breaks the problem into two independent linear scans, one per direction, and falls back to “Not Sorted” only when both fail.

  1. Handle the trivial case first: an array with 0 or 1 elements is always considered ascending.
  2. Write a helper method isSortedAscending that scans the array from index 1 to the end, returning false the moment any element is smaller than the one before it.
  3. Write a mirror helper method isSortedDescending that returns false the moment any element is larger than the one before it.
  4. In the main checking method, call isSortedAscending first; if it returns true, report the array as ascending.
  5. If the ascending check fails, call isSortedDescending; if it returns true, report the array as descending.
  6. If neither check passes, report the array as not sorted.

Java Program

Here is a complete, compilable Java program that implements the approach above.

Java
public class ArraySortOrderChecker {

    public static boolean isSortedAscending(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] < arr[i - 1]) {
                return false;
            }
        }
        return true;
    }

    public static boolean isSortedDescending(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > arr[i - 1]) {
                return false;
            }
        }
        return true;
    }

    public static String checkOrder(int[] arr) {
        if (arr.length <= 1) {
            return "Ascending";
        }
        if (isSortedAscending(arr)) {
            return "Ascending";
        }
        if (isSortedDescending(arr)) {
            return "Descending";
        }
        return "Not Sorted";
    }

    public static void main(String[] args) {
        int[] numbers = {2, 4, 6, 8, 10};
        System.out.println("Array order: " + checkOrder(numbers));
    }
}

Explanation of the Program

The method isSortedAscending loops once through the array, comparing arr[i] with arr[i - 1]. As soon as it finds a pair where the current element is smaller than the previous one, it returns false immediately, because that single pair proves the array cannot be ascending.

isSortedDescending mirrors this logic but flips the comparison: it returns false as soon as an element is larger than its predecessor.

checkOrder ties the two helpers together. It first rules out the trivial case of a 0 or 1 element array, then tries the ascending check, then the descending check, and falls back to Not Sorted only when both fail.

The main method simply calls checkOrder on a sample array and prints the result, giving you a quick way to confirm the logic compiles and runs.

Step-by-Step Trace

Let’s trace isSortedDescending on the array [8, 5, 5, 2, 7], which looks descending at first but breaks at the last element.

Iterationarr[i]arr[i – 1]arr[i] > arr[i – 1]?descendingSoFar (after)
158notrue
255notrue
325notrue
472yesfalse

At the end of each iteration, descendingSoFar is true only if every element compared so far did not increase from its predecessor. The moment index 4 shows an increase from 2 to 7, the method returns false immediately, without checking any remaining elements.

Examples

The following examples run checkOrder on three different arrays to show each possible outcome.

Example 1: Ascending Array

Java
int[] numbers = {1, 3, 5, 7, 9};
System.out.println(checkOrder(numbers));
// Output: Ascending

Example 2: Descending Array

Java
int[] numbers = {20, 15, 10, 5};
System.out.println(checkOrder(numbers));
// Output: Descending

Example 3: Not Sorted

Java
int[] numbers = {4, 1, 7, 3};
System.out.println(checkOrder(numbers));
// Output: Not Sorted

Common Mistakes to Avoid

These are the mistakes candidates most often make when solving this problem.

  • Using strict comparisons for ties – treating any equal adjacent pair as a failure rejects arrays with repeated consecutive values, even though a plateau of equal values is still non-decreasing. Compare with < or > only, so equal neighbors pass.
  • Skipping the length 0 or 1 guard – starting the loop at i = 1 on an empty or single-element array is safe in Java, but forgetting to think through this case leads to confusing results if the loop bounds are later rewritten. Handle arr.length <= 1 explicitly before the loop.
  • Reusing one flag for both directions – tracking ascending and descending state with a single boolean in one pass conflates the two conditions and misreports mixed arrays. Run two independent passes, one helper method per direction.
  • Assuming descending excludes ascending – an array where every element is equal, such as {5, 5, 5}, satisfies both isSortedAscending and isSortedDescending. Checking ascending first and documenting that convention avoids ambiguity in what gets reported.

Edge Cases to Test

Before calling the solution complete, walk through these boundary inputs.

  • Empty array
  • Single-element array
  • All elements equal
  • Two-element ascending pair
  • Two-element descending pair
  • Ascending run followed by one descending dip
  • Integer.MIN_VALUE and Integer.MAX_VALUE adjacent
  • Null array reference

Additional Considerations

Time and Space Complexity

Each helper method makes a single pass over the array, so the cost is O(n) time per direction, and O(n) overall since the descending check only runs after the ascending check has already failed. Both helpers use a fixed number of local variables, so the space complexity is O(1) beyond the input array.

Comparisons use < and > directly on int values rather than subtracting elements, so there is no risk of integer overflow even when the array contains Integer.MIN_VALUE or Integer.MAX_VALUE.

Trade-offs

Checking both directions in separate passes keeps the code easy to read, but it means a descending array is only confirmed after the ascending check has already scanned the whole array once. A single combined pass that tracks two boolean flags at the same time would avoid that duplicate work, at the cost of slightly less readable code.

Interview Follow-up Questions

An interviewer rarely stops at the base problem. Be ready for these follow-ups.

  • What if the array has many duplicate values? – clarify whether “sorted” means strictly increasing or merely non-decreasing, then adjust the comparison operators between < and <= accordingly.
  • What if you need to check order in a single pass instead of two? – maintain two booleans, couldBeAscending and couldBeDescending, and update both inside one loop, short-circuiting once both become false.
  • What if the array arrives as a stream of unknown length? – track only the previous element and the direction decided so far; there is no need to store the whole array in memory.
  • What if the array is read-only and too large to fit in memory? – process it in fixed-size chunks, comparing the last element of one chunk to the first element of the next to carry the sort direction across chunk boundaries.

Conclusion

Checking whether an array is sorted in ascending or descending order comes down to two simple linear scans, each one bailing out the moment it finds a pair of elements that breaks the expected order. Once you’re comfortable with this pattern, you can adapt it to detect strictly increasing or non-decreasing variants just by adjusting the comparison operators.

Try modifying the program above so it also reports whether the array is strictly sorted, or combine both direction checks into a single pass. You can learn more about array-based problems here: https://dailyjavaconcept.com/category/arrays/