In the below code example, I'm trying to solve the Longest Word in Dictionary Through Deleting question on Leetcode. I think this solution should work, but for some reason the nested while loops below seem to break the function, and I can't figure out why.

The error I'm receiving is "Line 20: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1." With that said, I don't know how this error is happening at all when I have multiple checks to ensure this doesn't happen. Additionally, the wrapper for loop seems to be called more times than the number of indices in the dictionary.

The closest I found to figuring out what could be going wrong is by placing a println(i) at the top of the wrapper For loop, and commenting out the indicated While loops inside the wrapper Do - While loop.

When those inner loops are uncommented, the function seems to be on it's way to getting the answer, but for loop prints 0,1,2,3,0 and the function returns the error "Line 20: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1." When I comment out those loops, the function properly prints 0,1,2,3 and finishes returning an incorrect answer.

I have no idea why those loops are causing the wrapper For loop to run additional times from 0 and return that error of 1. Is that even the problem?

class Solution {
    fun findLongestWord(s: String, dictionary: List<String>): String {
        var answer = ""

        for (i in dictionary.indices) {
            
            // Printing i to test the iterations of function
            // Prints 0, 1, 2, 3 when below while loops are commented out
            // Prints 0,1,2,3,0 when the below two while loops aren't commented out.
            println(i)
            if (answer.length > dictionary[i].length) {
                
                continue
            }
            var tempString = s.toCharArray().toMutableList()
            
            var low = 0
            var dictLow = 0
            var high = tempString.lastIndex
            var dictHigh = dictionary[i].lastIndex
          
            do {
                // Commenting out the below two while loops causes function to work
                while (tempString.size >= answer.length && tempString.isNotEmpty() && tempString[low] != dictionary[i][dictLow] ) {
                    tempString.removeAt(low)
                    high -= 1

                }

                while (tempString.size >= answer.length && tempString.isNotEmpty() && tempString[high] != dictionary[i][dictHigh]) {
                    tempString.removeAt(high)
                    high -= 1
                }

                if (tempString.joinToString("") == dictionary[i]) {
                    var potentialAnswer = tempString.joinToString("")
                    if (potentialAnswer.length > answer.length) {
                        answer = potentialAnswer
                    } else if (potentialAnswer.length == answer.length) {
                        var list = mutableListOf(potentialAnswer, answer).sorted()
                        answer = list[0]
                    }
                    break
                }
                else {
                    low += 1
                    high -= 1
                    dictLow += 1
                    dictHigh -= 1
                }
                

            } while (tempString.size > answer.length && low < high) 
        }

        return answer
    }
}
1

There are 1 best solutions below

4
AndrewL On

I don't understand what you are trying to achieve, but here is something to check:

In

while (tempString.size >= answer.length 
&& tempString.isNotEmpty() && tempString[low] != dictionary[i][dictLow] ) {

the only part of this I think could raise StringIndexOutOfBoundsException is dictionary[i][dictLow]. You start dictLow=0 and increment this later, but you have no guard condition, so inevitably, I presume, you will come across a String that has fewer characters than dictLow... hence the Exception