The problem is this line:
return smallestLetter(str.substring(0) + str.substring(2,str.length()));
str.substring(0)
is actually the entire string; so in this line, the method re-calls itself with a string that's almost twice as big as the original. Just a few method-calls in, you can already have a massive string that's bigger than you can allocate.
The minimal fix is:
return smallestLetter(str.charAt(0) + str.substring(2,str.length()));
but a better fix is to use iteration rather than recursion:
public static String smallestLetter(String str) {
char ret = str.charAt(0);
for (int i = 1; i < str.length(); ++i)
if (str.charAt(i) < ret)
ret = str.charAt(i);
return String.valueOf(ret);
}
Edited to add: Note that, as Alexey Malev points out below, this will raise an exception if str
is the empty string (""
). In addition, it does not do any filtering to specifically identify letters; rather, it will return the least character in the string, whether or not that's a letter.