-1

I am writing a simple program to find the longest palindrome in a string. What I'm doing is checking if each substring is a palindrome and then checking its length. If the length is greater than the previous length, then I have the new longest substring. For example, "babad", would return "bab" or "aba", either is fine. But my issue is that I get index out of bounds on my substring call and I can't figure out why.

public class LongestPal{
    public static void main(String[] args)
    {
        String test = new String("babad");
        String result = longestPalindrome(test);

    }
    public static String longestPalindrome(String s) {
        int length = 0;
        String answer = new String();

        for(int i = 0;i<=s.length();i++)
        {
            for(int j = 0; j<= s.length();j++)
            {
                String subStr = s.substring(i,j); // Get all substrings
                System.out.println(subStr); // Checking to see if all are printed

                boolean result = isPalindrome(subStr); //Check for palindrome
                if(result)
                {
                    if(length < subStr.length()) //If length of new substr is greater than the old one, 
                                                //the new answer will be longer substring
                    {
                        answer = subStr;   
                    }
                }
            }
        }
        return answer;
    }
    public static boolean isPalindrome(String s) //Recursive palindrome checker
    {
        if(s.length() == 0 || s.length() == 1)
            return true; 
        if(s.charAt(0) == s.charAt(s.length()-1))
            return isPalindrome(s.substring(1, s.length()-1));
        return false;
    }
}

When I print out, I get all the substring combinations, until "babbad" after that is when the error occurs.

Pang
  • 9,564
  • 146
  • 81
  • 122
GreenSkies
  • 141
  • 1
  • 10

4 Answers4

0

So the error in my code turned out to be when i>j as pointed out by some of the people in the comments. Thus, simply making j=i when searching for palindromes resolved the issue.

You'll also notice that you don't ever see length change and this is another error in the code. Once the answer is updated, the length must be changed to the length of the answer. A simple fix for this is making length = subStr.length() in the second "if" statement.

The algorithm still not fast as it will run with complexity of O(n^3).

GreenSkies
  • 141
  • 1
  • 10
0

shouldn't you be iterating from 0 to s.length-1 ? which would mean your loop condition to be:

for(int i = 0;i<s.length();i++)

and a similar one for the next loop with j

Not doing that could result in index out of bounds for sure.

Gangz
  • 11
  • 3
  • The change made doesn't really result in a different answer. Both ways still get me to the same result whether is be <= or <. – GreenSkies Dec 30 '16 at 02:36
  • by no change i assume you mean you still get the index out of bound exception? I think you do need to re-write the algo, its is close to O(n^3) and not )(n^2). the substring method is also O(n) cost process. i expect it to be really slow. also not making sure j – Gangz Dec 30 '16 at 02:49
  • Oh no, by no change I mean the index out of bounds was fixed, but changing from <= to < both give me the right answers. And yea it is closer to O(n^3), I overlooked the substring method. – GreenSkies Dec 30 '16 at 02:52
0

You need to change your loop condition. It should be only < not <=. Because If you check the length of 'babad' it will give you 5 but index start from 0 and end on 4 for this. So you need to change the loop condition and it will solve the problem.

Ahmar
  • 3,717
  • 2
  • 24
  • 42
  • I did change it, but seemed to have no affect on the test cases that I was running it against. Is there any reason for this occurrence ? – GreenSkies Dec 30 '16 at 02:38
0

Part A of the problem - Compiler error

  1. Change your outer loop from for(int i = 0;i<=s.length();i++) to for(int i = 0;i<s.length();i++) as others have pointed out.
  2. Change your inner loop from for(int j = 0; j<= s.length();j++) to for(int j = i; j< s.length();j++).

Your program is giving you out of bound exception because in the second iteration of your outer loop, your i becomes 1 and j starts from 0. And then you call the String's substring method as s.substring(1,0); which obviously gives you this exception.

Make the corrections as suggested and go from there on. Let us know if you need more help.

Part B of the problem - Faster algorithm

Here's a more efficient algorithm. I believe this should be the fastest one too.

    public static void main(String[] args) {        
    String s = "babad";

    int starter = 0;

    if(s.length() % 2 == 0) 
        starter = 1;

    String answer = "";
    Boolean found = Boolean.FALSE;
    while(starter < s.length() - 1) {
        for(int i=0; i<=starter; i++) {
            if(isPelindrom(answer = s.substring(i, i+ s.length() - starter))) {
                found = Boolean.TRUE;
                break;
            }
        }
        if(found) break;
        starter = starter + 1;          
    }
    if(!found) answer = String.valueOf(s.charAt(0));
    System.out.println("The answer is " + answer);

}

public static Boolean isPelindrom(String s) {
    return s.equalsIgnoreCase(new StringBuilder(s).reverse().toString());
}

Let me know if you need additional help.

VHS
  • 9,534
  • 3
  • 19
  • 43
  • The solution works, but it is terribly slow going around O(n^3), now this works for smaller test cases. But given a very large string, there is no doubt I will run into problems. – GreenSkies Dec 30 '16 at 02:53
  • That's a different problem from the one you had originally highlighted in the main post. Please post your question as a separate post. Stackoverflow doesn't normally allow users to post questions related to better or faster coding – VHS Dec 30 '16 at 04:00
  • Oh I know that completely, I'm just mentioning it because the other solution was solved. I going to work on it for a while, but I appreciate your concern. – GreenSkies Dec 30 '16 at 04:44
  • Cool. I have made an edit to the answer. I have provided a sample algorithm that should take fewer iterations than yours. Let me know if you face any other issues. – VHS Dec 30 '16 at 05:00
  • Actually, with the edits you made I failed a test case I was previously passing. The test case is "cbbd" where the answer should be "bb". – GreenSkies Dec 30 '16 at 05:06
  • Hmm. I was thinking that a palindrome will always be an odd in length. If it can be even too, we need to increment the starter by 1 at a time instead of 2. Updated. – VHS Dec 30 '16 at 05:17