LeetCode OJ-5.Longest Palindromic Substring(最长回文子串)
2016-12-27 14:31
591 查看
LeetCode OJ-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"
题目理解
题目是要求解最长的回文子串,回文串说的是正着写和反着写结果都是一样的字符串,具体可以看个例子:”bab”就是一个回文串,”aa”也是一个回文串。形式则是第1个字符与第n个字符相等,第2个字符与第n - 1个字符相等,第3个字符与第n - 2个字符相等,以此类推。时间复杂度为O(n^3)的暴力解法
简单的解法可以从回文串的基本形式想到,可以从某个子串的起始与结束位置向中间渐渐靠拢,若出现不相等的情况,则说明这个子串不可能是回文串。由此可以得到一个时间复杂度为O(n^3)的解法,其中起始位置在最外层循环迭代,而结束位置这里不直接进行迭代,而是在第二层进行子串长度的迭代,则结束位置则为len - 1,最内层循环则是由两边向中间靠拢去判断是否为回文串。PS: 这个解法会超时,仅是提供一种思路。具体代码如下:int get_longest_palindromic_substr(const char *str, int *start, int *end, size_t sz) { int res = 0; int i, j; int k, l; for (i = 0; i < sz; ++i) { for (j = 1; j < sz && i + j < sz; ++j) { k = i; l = j; while (k < l) { if (str[k] == str[l]) { if (k + 1 < l) { ++k; --j; } else { break; } } else { break; } } if (k + 1 == l && str[k] == str[l] && j - i + 1 > res) { *start = i; *end = j + 1; //本来这里应该是j + 1,但若要使用string构造函数中以 //迭代器构造的形式,就需要移动到结束位置后一个位置。 res = j - i + 1; } else if (k == l && j - i + 1 > res) { *start = i; *end = j + 1; //本来这里应该是j + 1,但若要使用string构造函数中以 //迭代器构造的形式,就需要移动到结束位置后一个位置。 res = j - i + 1; } } } return res; }
时间复杂度为O(n^2)的动态规划解法
使用动态规划可以将时间复杂度降为O(n^2),思路与上面的方法类似,只是引入了一个记录状态的dp数组,空间复杂度提升为O(n^2)。 设dp[i][j]为判断从i到j位置的子串是否为回文串的标志,是则为true,不是则为false。状态方程可写作:
dp[i][j]={ dp[i + 1][j - 1], str[i] == str[j] | dp[i][i], i == j | dp[i][i + 1] str[i] == str[i + 1] }.
对于状态方程的三种状态有如下解释:
当str[i] = str[j]时,dp[i][j]的值由i + 1与j - 1对应的dp值决定,即也是一个从两端向中靠拢判断的过程;
当i = j时,当个的字符自然是回文串,则常为true;
相邻位置的字符构成的子串是否为回文串,则看i和i + 1位置的字符是否相等,相等即为true。
有了上述定义,则可以得到代码,对于一些特殊的处理,代码关键位置有注释可参看:
const int g_kMaxSize = 1001; int get_longest_palindromic_substr(const char *str, int *start, int *end, size_t sz) { int max_len = 1; bool dp[g_kMaxSize][g_kMaxSize] = { false }; int i, j; int len; *start = 0; *end = 1; for (i = 0; i < sz; ++i) { dp[i][i] = true; } for (i = 0; i < sz - 1; ++i) { if (str[i] == str[i + 1]) { dp[i][i + 1] = true; *start = i; *end = i + 2; //本来这里应该是i + 1,但若要使用string构造函数中以迭代器构造 //的形式,就需要移动到结束位置后一个位置。 max_len = 2; } } for (len = 3; len <= sz; ++len) { for (i = 0; i < sz; ++i) { j = i + len - 1; if (j < sz && str[i] == str[j] && dp[i + 1][j - 1]) { dp[i][j] = true; *start = i; *end = j + 1; //本来这里应该是j + 1,但若要使用string构造函数中以 //迭代器构造的形式,就需要移动到结束位置后一个位置。 max_len = len; } } } return max_len; }
相关文章推荐
- LeetCodeOJ_5_m_Longest Palindromic Substring(最长回文子串)
- LeetCode_5---Longest Palindromic Substring (求最长回文子串)
- 求最长回文子串 - leetcode 5. Longest Palindromic Substring
- leetcode(5)—— Longest Palindromic Substring(最长回文子串)
- 【LeetCode-面试算法经典-Java实现】【005-Longest Palindromic Substring(最长回文子串)】
- LeetCode-5-Longest Palindromic Substring 最长回文子串DP
- Longest Palindromic Substring [LeetCode] 最长回文子串
- LeetCode-5 Longest Palindromic Substring(求最长回文子串)
- LeetCode:Longest Palindromic Substring 最长回文子串
- Longest Palindromic Substring 在一个字符串里找最长回文子串@LeetCode
- leetcode5-Longest Palindromic Substring(最长回文子串)
- LeetCode---5. Longest Palindromic Substring(最长回文子串)
- leetcode Longest Palindromic Substring最长回文子串
- LeetCode-Longest Palindromic Substring-最长回文子串-Manacher
- LeetCode 5 Longest Palindromic Substring(最长回文子串,暴力剪枝/DP/曼彻斯特算法)
- [Leetcode] Longest palindromic substring 最长回文子串
- LeetCode题库解答与分析——#5.最长回文子串LongestPalindromicSubstring
- [C++]LeetCode 5: Longest Palindromic Substring(最长回文子串)
- LeetCode 5. Longest Palindromic Substring(最长回文子串)
- LeetCode | Longest Palindromic Substring(最长回文子串)