Definition
- Adjacent comparison – check each element against its immediate neighbour.
- Fail fast – return
falseat the first violation to avoid unnecessary work. - Trivially sorted – empty and single-element arrays pass because there are no pairs to violate.
- Ordering policy –
<=allows duplicates (non-strict);<requires strictly increasing. - O(n) time, O(1) space – one pass through the array with no extra data structures.
National Bank of India produces a daily settlement file where transactions must already be ordered by timestamp. A clerk walks down the rows comparing each row's time with the next. The instant a later row has an earlier time, the file is flagged as out of order. If every pair is in order all the way down, the file passes.
Understanding the Concepts
What is the problem?
Given an array, determine whether it is sorted in ascending order. In a banking context, the settlement ingestion pipeline at National Bank of India requires that incoming files are pre-sorted by timestamp. A failed check means the file must be rejected.
How does the algorithm work?
Loop from the first element to the second-to-last. At each position i, compare arr[i] with arr[i+1]. If arr[i] is greater than arr[i+1], return false immediately. If the loop completes, return true.
package com.bank.service;
import java.math.BigDecimal;
public class SortOrderValidator {
public static boolean isSortedAscending(BigDecimal[] arr) {
if (arr == null || arr.length <= 1) {
return true;
}
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i].compareTo(arr[i + 1]) > 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
BigDecimal[] sorted = {
new BigDecimal("1000"),
new BigDecimal("2500"),
new BigDecimal("2500"),
new BigDecimal("7800")
};
BigDecimal[] unsorted = {
new BigDecimal("1000"),
new BigDecimal("7800"),
new BigDecimal("2500")
};
System.out.println("Sorted array: " + isSortedAscending(sorted));
System.out.println("Unsorted array: " + isSortedAscending(unsorted));
}
}
Sorted array: true
Unsorted array: false
What about empty and single-element arrays?
Both are trivially sorted because there are no adjacent pairs to violate the ordering. The loop simply does not execute, and the method returns true.
What is the difference between strict and non-strict ordering?
Non-strict ascending (<=) allows equal neighbours, treating [1000, 2500, 2500, 7800] as sorted. Strict ascending (<) rejects it because 2500 appears twice. Choose based on the requirement: timestamps that can tie need non-strict; unique identifiers need strict.
// Non-strict: allows duplicates
if (arr[i].compareTo(arr[i + 1]) > 0) return false;
// Strict: rejects duplicates
if (arr[i].compareTo(arr[i + 1]) >= 0) return false;
How do you make it reusable with a Comparator?
Accepting a Comparator makes the same method work for ascending, descending, or custom orders.
import java.util.Comparator;
public static <T> boolean isSorted(T[] arr, Comparator<T> cmp) {
for (int i = 0; i < arr.length - 1; i++) {
if (cmp.compare(arr[i], arr[i + 1]) > 0) {
return false;
}
}
return true;
}
// Usage: check descending order
boolean desc = isSorted(arr, Comparator.reverseOrder());
Why does fail-fast matter?
On a large settlement file with millions of rows, returning false at the first violation avoids scanning the remaining rows. When the file is corrupted near the top, this saves significant time in a batch pipeline.
What is the time and space complexity?
- Time: O(n) in the worst case when the array is fully sorted (every pair must be checked).
- Best case: O(1) when the first pair is out of order.
- Space: O(1) because no extra data structures are needed.
What are common mistakes?
The most common mistake is looping to arr.length instead of arr.length - 1, which causes an ArrayIndexOutOfBoundsException when accessing arr[i + 1]. Another mistake is forgetting to handle the null or empty array.
// Wrong: index out of bounds
for (int i = 0; i < arr.length; i++) {
if (arr[i].compareTo(arr[i + 1]) > 0) // crashes at last element
}
// Correct: stop one before the end
for (int i = 0; i < arr.length - 1; i++) { /* safe */ }
What should a senior engineer know?
A senior engineer uses the Comparator-based approach for reusability and documents the duplicate policy. The senior also mentions that checking whether an array is sorted is often a precondition guard: if the downstream algorithm requires sorted input (like binary search), the check prevents silent wrong results. In the settlement pipeline, Pankaj uses this check as a gate before the reconciliation engine, which assumes sorted input.
Visual Overview
arr[]: 1000 2500 2500 7800
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────────────────────────────────┐
│ i=0: 1000 > 2500? NO (ok) │
│ i=1: 2500 > 2500? NO (equal, ok) │
│ i=2: 2500 > 7800? NO (ok) │
└──────────────────────────────────────────┘
No violation found → return true
arr[]: 1000 7800 2500
┌──────────────────────────────────────────┐
│ i=0: 1000 > 7800? NO (ok) │
│ i=1: 7800 > 2500? YES → return false │
└──────────────────────────────────────────┘
Fail fast at first violation
Key Takeaway
Checking whether an array is sorted is a single pass over adjacent pairs. For ascending order I compare each element with the next and return false the moment I find a violation. If the scan completes, the array is sorted. It is linear time, constant space, and fails fast.
Empty and single-element arrays are trivially sorted. I decide strict versus non-strict ordering deliberately: non-strict allows equal neighbours, which is right when duplicates are legitimate, while strict enforces uniqueness.
To make it reusable I accept a Comparator so the same loop checks ascending, descending, or any custom order. Fail-fast matters in practice: on a large settlement file that is corrupt near the top, returning at the first violation avoids scanning millions of remaining rows.
In my banking project at National Bank of India I used this as a gate in the settlement ingestion pipeline, because the downstream reconciliation engine assumes sorted input.
Remember one sentence: compare adjacent pairs and return false at the first violation, return true only if every pair passes.
---