Created
April 14, 2020 15:10
-
-
Save jatinsharrma/226839204b12998c5d8eb61c6d083094 to your computer and use it in GitHub Desktop.
Longest Palindromic Substring
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #--------- Longest Palindromic Substring------------------ | |
| ''' | |
| Logic: | |
| we know that a palindrome can be of even or odd length | |
| For example "aba" here b is center and in "abba" center is between 2 "b"s | |
| In below logic we will be using this knowledge | |
| Everytime we will make 2 assumptions | |
| 1. Current node is center of the palindrome (odd length) | |
| 2. Just before current node there is a center of palindrome (even length) | |
| About getPalindrome Function: | |
| It takes a string and 2 index values as parameters. Lets say one index is left and other index value is right. | |
| This function see whether characters at given indexes are equal | |
| 1. If equal then left will move one index left and right moves right one index and this will continue till left reaches index 0 or right reaches | |
| last index of string (because after these conditions we will go out of bound) | |
| 2. If characters are not equal on given indexes then obviously it violates the palindrome condition so we break loop there only | |
| This function will return left+1 and right indexes where ever loop stops | |
| example : we pass ("aba",0,2) | |
| function will see character at index 0 (i.e a) and character at index 2 (i.e a) is equal or not. | |
| Yes they are equal so now left index will go one left it will become -1 where as right become 3. Left index is less than 0 so loop will break | |
| we found out that max palindrome is between 0 to 2, So we will return [0,3]. | |
| Suppose we are given ("ahafghiihgfabbb"). Lets create a list which will store our result,[] | |
| We will remember the indexes here | |
| We start with index 0. | |
| It is the first character and alone it is a palindrome, there is nothing to the left of it. So we will go to next index i.e 1. | |
| We found out max length palindrome till now is "a" so we will update our result list [0,1] | |
| Now lets take index 1 | |
| cases: | |
| 1. If b is center that means characters to the left of it and to the right should be equal. | |
| We will pass index of left character i.e. 0 and right character i.e 2 to our getPalindrome function. | |
| From getPalindrome function we will get [0,3] | |
| 2. If center is just before b then we will pass index 0,1 to getPalindrome function | |
| we will get [0,1] | |
| Now we will see among these two cases and the value stored in result list which is max. (for getting max we are taking differences of indexes) | |
| So we get maximum of all is case 1, so our result became [0,3] | |
| index 2 | |
| cases : | |
| 1. If a is center, we get [2,3] | |
| 2. If center is just before a, we get [2,2] | |
| max of all is result values only so no changes | |
| this will continue till index 6. Result values won't change | |
| index 7 | |
| cases: | |
| 1. If I is center, we will get [7,8] | |
| 2. If center is just before I, we get [3,11] | |
| max of all is 2nd case, so we update result to [3,11] | |
| This will continue till the end | |
| so our result id ("fghiihgf") | |
| ''' | |
| String = "zzzzzzz2345abbbba5432zzbbababa" | |
| def longestPalindromicSubstring2(string): | |
| result = [0,1] | |
| for i in range(1,len(string)): | |
| odd = getPalindrome(string,i-1,i+1) | |
| even = getPalindrome(string,i-1,i) | |
| current = max(odd,even,key = lambda x: x[1]-x[0]) | |
| result = max(current,result,key=lambda x: x[1] - x[0]) | |
| return string[result[0]:result[1]] | |
| def getPalindrome(string,left,right): | |
| while left >= 0 and right < len(string): | |
| if string[left] != string[right]: | |
| break | |
| left -= 1 | |
| right += 1 | |
| return [left + 1, right] | |
| print(longestPalindromicSubstring2(String)) | |
| #----------------------------------------------------------------- | |
| #----------------------------------------------------------------- | |
| ''' | |
| For logic go to : https://gist.github.com/jatinsharrma/586fa6eb59a0ee37d10555a61eae60bc | |
| It is similar to that logic, finding all sequences and finding max palindrome among them. | |
| A little difference is that if suppose a string like "abba" is a palindrome we are not disintegrating that string | |
| because we will not find maximum palindrome from its substring | |
| ''' | |
| # iterative solution | |
| def longestPalindromicSubstring(String): | |
| result = "" | |
| buffer = [String] | |
| temp = [] | |
| while buffer: | |
| current = buffer.pop(0) | |
| if len(current) == 0 : break | |
| flag = palindrome(current) | |
| if flag: | |
| if len(current) > len(result): result = current | |
| continue | |
| if current not in temp: | |
| temp.append(current) | |
| buffer.append(current[1:]) | |
| buffer.append(current[:-1]) | |
| return result | |
| # recursive solution | |
| def longestPalindromicSubstring1(String, p_lindrome,memory): | |
| if len(String) == 1: | |
| return String if len(String) > len(p_lindrome) else p_lindrome | |
| if len(String) > len(p_lindrome) and palindrome(String): | |
| return String | |
| if String not in memory: | |
| memory.append(String) | |
| left = longestPalindromicSubstring1(String[1:],p_lindrome,memory) | |
| right = longestPalindromicSubstring1(String[:-1],p_lindrome,memory) | |
| length = [len(p_lindrome),len(left),len(right)] | |
| if length[1] > length[0]: | |
| if length[1] >= length[2]: | |
| p_lindrome = left | |
| elif length[2] > length [0]: | |
| p_lindrome = right | |
| return p_lindrome | |
| # this function see whether given string is palindrome or not | |
| def palindrome(string): | |
| if len(string) <= 1: return True | |
| mid = len(string)//2 | |
| flag = True | |
| for i in range(mid+1): | |
| if string[i] != string[-(i+1)]: | |
| flag = False | |
| break | |
| return flag | |
| String = "zzzzzzz2345abbbba5432zzbbababa" | |
| print(longestPalindromicSubstring1(String,"",[])) | |
| print(longestPalindromicSubstring(String)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment