TheAlgorithms/Java · error · IllegalArgumentException

Original index must be between 0 and {}, got: {}

Error message

Original index must be between 0 and {}, got: {}

What it means

BurrowsWheelerTransform.inverseTransform(String, int) reverses the transform using the original row index, which must point at a valid row in the n x n rotation table — i.e. an index in [0, n-1]. An index outside that range cannot locate the correct starting row, so the method rejects it with the valid bounds echoed in the message.

Source

Thrown at src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java:178

     *   <li>Following this mapping starting from the original index to reconstruct the string</li>
     * </ol>
     * </p>
     *
     * @param bwtString the transformed string (L-column) from the forward transform; must not be {@code null}
     * @param originalIndex the index of the original string row from the forward transform;
     *                      use -1 for empty strings
     * @return the original, untransformed string; returns empty string if input is empty or {@code originalIndex} is -1
     * @throws NullPointerException if {@code bwtString} is {@code null}
     * @throws IllegalArgumentException if {@code originalIndex} is out of valid range (except -1)
     */
    public static String inverseTransform(String bwtString, int originalIndex) {
        if (bwtString == null || bwtString.isEmpty() || originalIndex == -1) {
            return "";
        }

        int n = bwtString.length();
        if (originalIndex < 0 || originalIndex >= n) {
            throw new IllegalArgumentException("Original index must be between 0 and " + (n - 1) + ", got: " + originalIndex);
        }

        char[] lastColumn = bwtString.toCharArray();
        char[] firstColumn = bwtString.toCharArray();
        Arrays.sort(firstColumn);

        // Create the "next" array for LF-mapping.
        // next[i] stores the row index in the last column that corresponds to firstColumn[i]
        int[] next = new int[n];

        // Track the count of each character seen so far in the last column
        Map<Character, Integer> countMap = new HashMap<>();

        // Store the first occurrence index of each character in the first column
        Map<Character, Integer> firstOccurrence = new HashMap<>();

        for (int i = 0; i < n; i++) {
            if (!firstOccurrence.containsKey(firstColumn[i])) {

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Pass the exact originalIndex returned by the forward transform — it must satisfy 0 <= index < bwtString.length().
  2. Store the index together with the BWT string so the pair cannot get out of sync.
  3. Use -1 as the sentinel for empty strings (it returns "" instead of throwing).

Example fix

// before
String original = BurrowsWheelerTransform.inverseTransform(bwt, storedIndex);

// after
if (storedIndex < 0 || storedIndex >= bwt.length()) {
    throw new IllegalArgumentException("Index " + storedIndex + " out of range for BWT of length " + bwt.length());
}
String original = BurrowsWheelerTransform.inverseTransform(bwt, storedIndex);
Defensive patterns

Strategy: validation

Validate before calling

if (originalIndex < 0 || originalIndex >= bwtString.length()) {
    throw new IllegalArgumentException("originalIndex " + originalIndex + " out of bounds [0," + (bwtString.length() - 1) + "]");
}
String original = BurrowsWheelerTransform.inverseTransform(bwtString, originalIndex);

Prevention

When it happens

Trigger: Calling inverseTransform(bwt, -2) (negative other than the sentinel -1); inverseTransform("abc", 5) (index >= length 3); inverseTransform with an index produced by a mismatched transform.

Common situations: The originalIndex stored alongside the BWT was corrupted or came from a different transform; an off-by-one when persisting/reading the index; index default-initialized to a value like Integer.MAX_VALUE.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/6bd793015e3343ec. Report an issue: GitHub.