Find the largest palindrome in any given string, using Python (large O notation)

advertisements

I was wondering which kind of O notation this code is, can somebody help me to figure out? I wrote it but when I was interrogated about which kind of O notation is, and the only thing I could say it was linear but I have the feeling that recursion+iteration should be exponential?

listPlindromes = []

def palindrome( givenString, n ):
    if n == 1:
        #print givenString
        return None
    else:
        #print givenString[:n]
        #print ('forward: '+givenString[:n] +'  backwards: '+givenString[:n][::-1])

        #Get difference between lengths
        lenDifference = len(givenString) - len(givenString[:n])

        #If there is a difference means there at least one more word/palindrome could exist
        #therefore it need to be tested
        if lenDifference > 0:
            for xTest in range(0,lenDifference-1) :
                newWord=givenString[xTest:n+xTest]
                if newWord == newWord[::-1]:
                    if len(newWord) > 0:
                        listPlindromes.append(newWord)
                        #print newWord
        else:
            if givenString[:n] == givenString[:n][::-1]:
                    listPlindromes.append(givenString[:n])
            #print('palindrome: '+givenString)

        return palindrome(givenString,n-1)

givenString='osooso'

palindrome(givenString, len(givenString))
print(listPlindromes)


The code you've got there runs in linear time; that is, its primary bottleneck is how large the string you give it is.

That said, there are some things that can be improved:

  • You only need to pass in the string
  • A string of length 1 is a palindrome
  • There's a lot of unnecessary/unneeded checks for length; simply slicing the string in half would be sufficient to start your checks

As for the iterative + recursive approach, it really depends on how it's authored, but I have a recursive approach in mind which could be O(n) as well.

  • Start with the whole string.
  • If the two ends match:
    • If the length of one side* of the string is greater than 1, take a slice of it from that position up to 1 less than the last character.
    • Invoke function.
  • If the two ends match and the length of one side* of the string is less than or equal to 1, we're done - return true.
  • Otherwise:
    • Return false, as we've found a mismatch.

*: Regardless if the string is even or odd, cutting it in half will give you an even number of characters on both sides.