文章目录如下
(1)自己的思路
(2)自己的代码
(3)别人的思路
(4)别人的代码
(5)对比自己的不足之处
题目如下:
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
(1)自己的思路
a.因为回文数是对称位置的字符相等,所以可以用栈来解决,因为栈的结构是先进后出,本身就具有对称性。
b.首先在遍历原字符串的每一个字符s[i]的时候,每个s[i]都需要跟栈顶元素相比较,当与栈顶相同时,说明与s[i]的对称位置上有一个与s[i]相同的元素,此时将s[i]存放在临时的回文数字符串tmppalindromic之中,并将栈顶的元素pop出。
c.当栈顶元素与s[i]不相同的时候,那么直接将s[i]push到栈中。并且此时代表着栈里面已经没有回文数字符串了,这个时候要把tmppalindromic保存到容器vector中。并将tmppalindromic初始化(tmppalindromic="")
d.当遍历完所有元素的时候,只需要比较vector中每个 tmppalindromic的长度即可,取出长度最长的tmppalindromic
e.因为栈只保存了回文数字符串一半的元素,所以返回之前,要还原原始的回文字符串。
(2)自己的代码
class Solution { public: string longestPalindrome(string s) { if (s.size() == 1) return s; bool popfinish = false; string tmppalindromic = ""; vector<string> v; stack<char> st; for (int i = 0; i < s.size(); i++) { if (popfinish&&tmppalindromic.size() != 0) { v.push_back(tmppalindromic); tmppalindromic.clear(); } if (st.empty() || st.top() != s[i]) { st.push(s[i]); popfinish = true; } else if (st.top() == s[i]) { tmppalindromic.append(&s[i]); st.pop(); popfinish = false; } } if (tmppalindromic.size() != 0) v.push_back(tmppalindromic); string longestpalindromic = ""; int longestlen = 0; for (int j = 0; j < v.size(); j++) { if(v[j].size()>longestlen) { longestlen = v[j].size(); longestpalindromic = v[j]; } } string reverselongestpalindromic = longestpalindromic; reverse(reverselongestpalindromic.begin(), reverselongestpalindromic.end()); return reverselongestpalindromic+longestpalindromic; } };
(3)别人的思路
a.使用动态规划的思想
b.构建二维数组f[j][i],以此用来表示下标j到下标i的范围的字符是不是一个回文字符串,如果f[j][i]为true,那么原始字符串s中,以s[j]为开始,以s[i]为结束字符串(包括s[j],s[i])构成一个回文字符串,否则,则不是。
c.判断一段字符是否为回文字符串的标准有两个,一个是整个字串只有两/相同的字符(eg:aa)或只有一个字符a,即(s[j] == s[i]) &&(i - j < 2)
,或者是在回文字符串的基础上,又在该回文字符串的两边有添加上了两个相同的字符,即(s[j] == s[i])&&(f[j + 1][i - 1])
d.使用max_len保存当前最长回文字符串的长度,如果发现有新的更长的回文字符串,那么及时更新max_len的值,并且更改最长回文字符串的初始位置为j。
class Solution { public: string longestPalindrome(string s) { int const n = s.size(); bool f[n][n]; fill_n(&f[0][0], n * n, false); size_t max_len = 1, start = 0; for (size_t i = 0; i < s.size(); i++) { f[i][i] = true; for (size_t j = 0; j < i; j++) { f[j][i] = (s[j] == s[i] && (i - j < 2 || f[j + 1][i - 1])); if (f[j][i] && max_len < (i - j + 1)) { max_len = i - j + 1; start = j; } } } return s.substr(start, max_len); } };
(5)对比自己的不足之处
a.首先自己的那种方法不能处理axa这种回文字符串,当初看到这道题的时候对回文字符串理解有误。
b.不能解决aaaa这种情况。
别人的方法很巧妙地使用二维数组来表示回文字符串的开头与结尾,而且使用动态的规划的思想,这种做法很值得学习与借鉴