Brute-force approach

Here I present a few approaches to deduce “minimum insertions” required to convert a string into a palindrome.

The basic brute force approach is quite simple, given a string with length L, start comparing, the first character from left and the last character while scanning inwards.

Here is a basic test for a palindrome.

   L = len(s) 
   for i in range(L):
       if s[i] != s[L - i - 1]:
           return False,i,L-i -1
   return True,0,0

The above code returns True if the string is a palindrome or returns False with mismatching indices.

result,left,right = ispalindrome(“aba”) will return True,0,0 while result,left,right = ispalindrome(“abc”) will return False,0,2 indicating the characters at 0th position, a, does not match with character at 2nd position, c

Once the indices are found a basic recursive solution can be written to reflect the missing strings from the mismatching indices.

    p,l,r = ispalindrome(s)
    if not p: 
        if l == 0:
            s = s[r] + s
            s = s[0:l]+ s[r] + s[l:]
        return to\_palendrome\_left\_reflect(s)
        return s
def to\_Palendrome\_rigth\_reflect(s):
    p,l,r = ispalindrome(s)
    if not p: 
        if l == 0:
            s =  s + s[l]
            s = s[0:r+1] + s[l] + s[r+1:]
        return to\_Palendrome\_rigth\_reflect(s)
        return s

Some tests are as follows.

print to\_palendrome\_left\_reflect("abc")#cbabc

print to\_Palendrome\_rigth\_reflect("ab") #aba
print to\_Palendrome\_rigth\_reflect("abc")#abcba

To find which is smaller we write a quick function as shown below.

   L = len(s)
   left\_insertion = to\_palendrome\_left\_reflect(s)
   right\_insertion = to\_Palendrome\_rigth\_reflect(s)
   delta\_l = len(left\_insertion) - L
   delta\_r = len(right\_insertion) - L

   print "LEFT:",left\_insertion
   print "RIGHT:",right\_insertion
   if delta\_l < delta\_r:
       print "MIN-LEFT",delta\_l
       print "MIN-RIGHT",delta\_r

Its important to consider that above mentioned techniques ignores deletion or susbtitution.

Another approach which only calculates count, while considering all possible operations.

   if start == end:
       return 0
   if start == end -1:
       if s[start] == s[end]:
           return 0
       return 1
   if s[start] == s[end]:
       return findMinInsertions(s,start+1,end - 1)
       a = findMinInsertions(s,start,end - 1)
       b = findMinInsertions(s,start+1,end) 
       return min(a,b)+1

Dynamic Programming approach (fastest)

   n = len(s)
   table = [[0 for i in range(n)]  for j in range(n)]
   start = 0
   end = 0 
   for y in range(0,n-1):
       a = 0
       for  x in range(n):
           if x>y-1:
               table[y][x] = a
   return table[0][n-1]

This, by far is the fastest of all methods, but only works for string which are not already apalindrome , the trick is to have a n x n matrices and then fill in a particual order from left to right, increasing the gaps per row as shown below, for string abcde

0 1 2 3 4
0 0 1 2 3 
0 0 0 1 2 
0 0 0 0 1 
0 0 0 0 0

The M[0][n-1] is 3

Hope this helps.