2

I'm trying to find the shortest palindrome that one can create from S by by adding 0 or more characters in front of it. For example the shortest palindrome can be constructed from 'baaa' is 'aaabaaa'. The two functions that I'm using are given below. This works for this case for doesn't yield the shortest result in all cases.

public static boolean checkPalindrome(String s){

        for (int i = 0; i < s.length()/2; i++) {
            if (s.charAt(i) != s.charAt(s.length() - i - 1)) return false;
        }

        return true;

    }

    public static int makePalindrome(String s){
    int min = 0;
    StringBuilder str = new StringBuilder(s);
    for (int i = 1; i < s.length() ; i++) {
        str.insert(0, s.charAt(i));
        if (checkPalindrome(str.toString()) == true) {
            min = str.length();
            break;
        }

    }
    return min;
}

I can't seem to figure out what logical step am I missing.

3
  • 2
    Can you explain your current logic? Commented Jan 17, 2015 at 16:14
  • I'm appending a character in the front and checking is the result is a palindrome. Commented Jan 17, 2015 at 16:15
  • 1
    How do you choose that character? Commented Jan 17, 2015 at 16:19

4 Answers 4

10

Your helper method checkPalindrome seems correct. Your thinking is also correct (append characters until the result is a palindrome), but the way you're going about it is wrong.

To reiterate: Our logic is, while our result is not a palindrome, take the next character from the end (moving towards the start of the string) and append it to the prefix. So for the string "abcd", we would try

  • "" + "abcd" -> "abcd" -> false
  • "d" + "abcd" -> "dabcd" -> false
  • "dc" + "abcd" -> "dcabcd" -> false
  • "dcb" + "abcd" -> "dcbabcd" -> true, terminate

Here's a fixed version:

public static String makePalindrome(String base){
    String pref = "";
    int i = base.length() - 1;
    while(! checkPalindrome(pref + base)){
        pref = pref + base.charAt(i);
        i --;
    }
    return pref + base;
}
Sign up to request clarification or add additional context in comments.

1 Comment

But instead of prefix, if he tries a post fix, he only ends up with a total of 6 chars instead of the 7 chars you got in prefix. Wouldn't that be a better approach. Example: abcd -> abcdcba - 6 chars
0

I am not sure i understand the question but from what i understood you want to turn Strings like Hello to olleHello To do this, loop trhough each char of the string with like:

    String example = "Hello There Mate"; //our string
    StringBuilder exampleBuilder = new StringBuilder();
    for(int i=example.length()-1; i>0; i--)
        exampleBuilder.append(example.charAt(i));
    //Our loop, the reason why it is example.lenght-1
    //is because we want the first letter to appear only
    //1 time :)
    String finalString = exampleBuilder.toString()+example;
    //The final string, should be 'olleHello'
    System.out.println(finalString);

Hope thats what you are looking for :D

Comments

0

IDEONE: http://ideone.com/tawjmG

We can find the shortest Palindrome using the following logic:

Find the midpoint, loop from 0 to midpoint, length-1 to midpoint.

If palindrome, return

If not palindrome, add 1 to midpoint, do same logic

In code:

static String shortestPalindrome(String s) {
    if (s.length() == 1) return s;
    return recShortestPalindrome(s, s.length()>>1, 0);
}

static String recShortestPalindrome(String s, int mid, int add) {
    // AABBA[X]
    int fakeLen = s.length() + add;
    for (int i = 0; i < mid; i++) {
        char c1 = s.charAt(i);
        int p1 = fakeLen - 1 - i;

        if (p1 < s.length()) {
            char c2 = s.charAt(p1);

            if (c2 != c1) {
                return recShortestPalindrome(s, mid+1, add+1);
            }
        }
    }

    // found a pattern that works
    String h1 = s.substring(0, mid);
    String h2 = new StringBuilder(h1).reverse().toString();

    String ret = h1+h2;

    int midPoint = ret.length()/2;

    if (ret.length()%2 == 0 && ret.length() >= 2) {
        char c1 = ret.charAt(midPoint);
        char c2 = ret.charAt(midPoint-1);

        if (c1 == c2) {
            return ret.substring(0, midPoint) + ret.substring(midPoint+1, ret.length());
        }
    }

    return h1+h2;
}

Comments

0

Python Solution:

def isPalindrome(x):
    if x == "":
        return False

    r = ""
    r = str(x)
    r = r[::-1]

    return True if x == r else False

def makePalindrome(my_str):

    pref = ""
    i = len(my_str) - 1

    while isPalindrome(pref + my_str) == False:
        pref = pref + my_str[i]
        i -= 1

    return pref + my_str







my_str = "abcd"
print(makePalindrome(my_str))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.