1. Longest palindrome substring
subject
Give you a string s and find the longest palindrome substring in S.
Example 1:
Enter: s = "bad"
Output: "bab"
Explanation: "aba" is also the answer to the question.
Example 2:
Input: s = "cbbd"
Output: "bb"
Example 3:
Input: s = "a"
Output: "a"
Example 4:
Input: s = "ac"
Output: "a"
- 1 <= s.length <= 1000
- s consists only of numbers and English letters (uppercase and / or lowercase)
1.0 indent from both sides to the middle (violence)
This is actually a little bit of the optimization of the violent solution.
string longestPalindrome0(string s) { int size = s.size(); string result = ""; int leftIndex, rightIndex; for (int i = 0; i < size; i++) //size-i is the length of the substring to be verified { for (int j = 0; j <= i; j++) //i+1 is the number of substrings to be verified, and j is the subscript to start verification { leftIndex = j; rightIndex = j + size - i - 1; bool flag = true; while (leftIndex < rightIndex && flag == true) { if (s[leftIndex] != s[rightIndex]) flag = false; leftIndex++; rightIndex--; } if (flag == true) return s.substr(j, size - i); } } return result; }
Time complexity: O (n third party)
Space complexity: O (1)
1.1 dynamic planning
(this thing is really hard to write, so I won't write it)
State transition equation:
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-hkrajauc-1634992771138) (image-20211023181351022. PNG)]
Boundary conditions:
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-8mv6rqrz-163499251141) (image-20211023181426492. PNG)]
string longestPalindrome1(string s) { int size = s.size(); if (size < 2)return s; string result; int maxLength = 1; int beginIndex = 0; vector<vector<bool>> dp(size, vector<bool>(size, false)); //Create a size*size state to save the array, dp[i][j] indicates whether the strings from I to j are palindromes for (int i = 0; i < size; i++) //A single character must be palindrome, and the identification is true dp[i][i] = true; for (int length = 2; length <= size; length++) //Length is the length of the substring, starting from 2, because 1 is 1... { for (int leftIndex = 0; leftIndex < size; leftIndex++) //Left subscript of substring { int rightIndex = leftIndex + length - 1; if (rightIndex >= size)break; if (s[leftIndex] == s[rightIndex]) { if (rightIndex - leftIndex < 3) //Corresponding boundary conditions, s[i]==s[j], if i+1==j, the palindrome length is 2, and if i+2==j, the palindrome length is 3 dp[leftIndex][rightIndex] = true; else dp[leftIndex][rightIndex] = dp[leftIndex + 1][rightIndex - 1]; //The key to ensuring the above formula is that the length ranges from small to large. Assuming that the length is now 5, then dp[leftIndex + 1][rightIndex - 1] has been determined when lengrh is 3 } if (dp[leftIndex][rightIndex] && length > maxLength) { maxLength = length; beginIndex = leftIndex; } } } return s.substr(beginIndex, maxLength); }
Time complexity: O (n square)
Space complexity: O (n square)
In contrast to the violent solution, it actually uses an n-square space to replace the while in the violent solution
1.2 center expansion method
If the string is odd (bab type), you can start with a character in the middle and check whether it is palindrome from both sides, but if it is even (baab type), it is wrong to do so
. Here are two solutions
Think of consecutive characters as a whole
string longestPalindrome2(string s) { string result; int size = s.size(); int leftIndex, rightIndex; int maxLength = 0; for (int i = 0; i < size; i++) { int tempLength = 1; leftIndex = i - 1; rightIndex = i + 1; while (i + 1 < size && s[i + 1] == s[i]) //Group consecutive characters into a whole { i++; rightIndex = i + 1; tempLength++; } while (leftIndex >= 0 && rightIndex < size) //Start detection on both sides { if (s[leftIndex] != s[rightIndex]) break; leftIndex--; rightIndex++; tempLength += 2; } if (tempLength > maxLength) { maxLength = tempLength; result = s.substr(leftIndex + 1, tempLength); } } return result; }
Time complexity: O (n square)
Space complexity: O (1)
Generally use this. It's simple, fast and doesn't occupy memory
Insert #, bab becomes #b#a#b#, and baab becomes #b#a#a#b#, see if they are all odd numbers
string longestPalindrome2(string s) { string sourceString; for (auto& i : s) { sourceString.push_back('#'); sourceString.push_back(i); } sourceString.push_back('#'); string result; string tempresult; int size = sourceString.size(); int leftIndex, rightIndex; int maxLength = 0; for (int i = 0; i < size; i++) { int tempLength = 1; leftIndex = i - 1; rightIndex = i + 1; while (leftIndex >= 0 && rightIndex < size) { if (sourceString[leftIndex] != sourceString[rightIndex]) break; leftIndex--; rightIndex++; tempLength += 2; } if (tempLength > maxLength) { maxLength = tempLength; tempresult = sourceString.substr(leftIndex + 1, tempLength); } } for (auto& i : tempresult) if (i != '#') result.push_back(i); return result; }
Time complexity: O (n square)
Space complexity: O (n)
Do not consider odd and even, the occupied space is acceptable, and it is also commonly used
1.3 others
Manacher algorithm, time complexity: O (n), space complexity: O (n). It's a little difficult, and I won't. those who want to learn can go to Baidu (- #-!).