【LeetCode】5. Longest Palindromic Substring
来源:互联网 发布:java中的double类型 编辑:程序博客网 时间:2024/05/16 14:13
算法小白,最近刷LeetCode。希望能够结合自己的思考和别人优秀的代码,对题目和解法进行更加清晰详细的解释,供大家参考^_^
5. Longest Palindromic Substring
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example:Input: "babad"Output: "bab"
Note: “aba” is also a valid answer.
Example:Input: "cbbd"Output: "bb"
题目让找出最长的回文子串。这道题一开始只能想到枚举所有区间,再进行回文判断的方式,这样的方法肯定是会超时的,最后看了题解,说是要用动态规划。
本题的动规思路是,如果区间[i, j] (i<=j) 构成一个回文串,那么区间[i-1, j+1]构成回文串的充要条件是 str[i-1]==str[j+1], 因此基本的递推公式为:
dp[i, j] = dp[i+1, j-1] && str[i+1] == str[j-1]
dp[i, j]是bool型,表示区间 [i, j] 构成的子串是否是个回文串,显然这里 i<=j
注:这里使用的是左闭右闭区间,C++规范一般要求使用左闭右开区间
有了递推公式,接下来就得考虑初值了,很显然,dp[i, i] (i=0…n)是等于true的,但只有这一类的初值明显不够,无法完成递推计算,还需要d[i, i+1] 这类的初值,显然,d[i, i+1] = (str[i] == str[i+1])
OK, 递推公式和初值都有了,接下来就可以码代码了。
class Solution {public: bool dp[1000+5][1000+5]; string longestPalindrome(string s) { int len = s.length(); if (len == 1) return s; if (len == 2) { if (s[0] == s[1]) return s; else return s.substr(0, 1); } // 特殊情况直接返回 int beg = 0, end = 0; int maxlen = 1; memset(dp, false, sizeof(dp)); // 生成初值,即dp[i,i]和dp[i,i+1] for (int i = 0; i < len; ++i){ dp[i][i] = true; if (i+1 < len) { dp[i][i+1] = (s[i] == s[i+1]); if (dp[i][i+1]) { beg = i; end = i + 1; maxlen = 2; } } } // 利用递推公式,同时更新最大长度和对应的区间下标 for (int i = 2; i < len; ++i){ for (int j = 0; j+i < len; ++j){ dp[j][j+i] = ( dp[j+1][j+i-1] && (s[j] == s[j+i]) ); if (dp[j][j+i] && i+1 > maxlen){ beg = j; end = j + i; maxlen = i+1; } } } return s.substr(beg, maxlen); }};
将dp看做一个方阵,从递推公式中,我们可以观察到,dp[i, j] 的值只与其左下角的值dp[i+1, j-1] 有关,因此,从空间上来说,并没有必要记录所有的 i, j 组合,在更新时完全可以覆盖后续不再用到的空间,因此,只需要一个两行的数组就可以满足要求。
另一点要注意的时,由于更新时要使用左下角即靠前的值,因此要进行倒序更新,代码如下:
class Solution {public: bool dp[2][1000+5]; // 使用两行就够了 string longestPalindrome(string s) { int len = s.length(); if (len == 1) return s; if (len == 2) { if (s[0] == s[1]) return s; else return s.substr(0, 1); } int beg = 0, end = 0; int maxlen = 1; memset(dp, true, sizeof(dp)); // 主要是给第一行赋初值,即dp[i][i],全部为true // 第二行进行手动更新,对应之前代码中的dp[i, i+1] for (int i = len - 1; i - 1 >= 0; --i){ dp[1][i] = (s[i] == s[i-1]); if (dp[1][i]) { beg = i-1; end = i; maxlen = 2; } } for (int i = 2; i < len; ++i){ for (int j = len - 1; j - i >= 0; --j) { // 进行倒序更新,覆盖不再用到的值 dp[i%2][j] = (dp[(i%2)][j-1] && (s[j] == s[j-i])); if (dp[i%2][j] && i + 1 > maxlen){ beg = j - i; end = j; maxlen = i+1; } } } return s.substr(beg, maxlen); }};
上述方法的时间复杂度都是O(n^2),提交后也只是打败了20%的小伙伴。
还有一种中心扩展的方法,不过他的时间复杂度也是O(n^2),这里先不介绍了,题解里面说,还有一种O(n)的牛X方法,叫做Manacher算法,等以后有机会再慢慢研究
- LeetCode 5. Longest Palindromic Substring
- LeetCode --- 5. Longest Palindromic Substring
- LeetCode 5.Longest Palindromic Substring
- [Leetcode] 5. Longest Palindromic Substring
- [LeetCode]5.Longest Palindromic Substring
- [leetcode] 5. Longest Palindromic Substring
- LeetCode-5. Longest Palindromic Substring
- leetcode 5. Longest Palindromic Substring
- leetcode 5. Longest Palindromic Substring
- Leetcode 5. Longest Palindromic Substring
- LeetCode 5. Longest Palindromic Substring
- Leetcode 5. Longest Palindromic Substring
- leetcode 5. Longest Palindromic Substring
- LeetCode-5. Longest Palindromic Substring
- Leetcode 5. Longest Palindromic Substring
- leetcode 5. Longest Palindromic Substring
- LeetCode *** 5. Longest Palindromic Substring
- 【leetcode】5. Longest Palindromic Substring
- underscore.js
- react中使用AntDesign库 --- babel-plugin-import 配置
- 二分图
- ios开发之NSEnumerator
- php.ini 5.6解释
- 【LeetCode】5. Longest Palindromic Substring
- spark一千篇旅游日记0006 之 DataFrame(二)
- 计算机人生思考
- .Net Error 当前不会命中断点。在 XXX.dll 中找到了 XXXX 的副本,但是当前源代码与 XXX.dll 中内置版本不同。若要允许...
- 蓝桥杯训练:爆搜——酒店招待
- can‘t create table phone.#sql-ea8_2(error150)
- 【解题报告】Educational Codeforces Round 20
- POJ3620Avoid The Lakes
- hibernate4缓存org.hibernate.cache.NoCacheRegionFactoryAvailableException