TheAlgorithms/Java · error · IllegalArgumentException

Original index must be between 0 and

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.

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.

Appendix: 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)