Lc-5
categories: [LeetCode]
tags: [String, Dynamic Programming, Medium]
5. Longest Palindromic Substring
题目大意:
给定一个字符串s,返回最长回文子字符串。
解题思路:
首先拿到这道题,我们发现题目要求求最长子串,一般求最长或者最大之类的,我们都可以用动态规划的方法来做
动态规划的话其实就是根据之前的状态来判定当前的状态
我们用一个二维数组dp来表示当前遍历首尾字母中的字符串是否回文。
既然考虑首尾的话,我们可以用两个for loop去遍历不同字母为首字母或者尾字母的情况,
并且首字母下标绝对不能超过尾字母下标。
在forloop循环中, 因为一个字母本身也是一个回文字符串,
所以我们先判断当start下标等于end下标,即start和end都指向当前字母,dp[start][end] = true;
如果下标start所指的字母和下标end所指的字母不相同,则dp[start][end] = false;
如果start和end所指字母相同,我们则判断当前遍历字母的长度是否为1,2或者3
长度为1,则说明start和end指向同一个字母,
长度为2,例如 bb
长度为3,例如 bab
当长度大于3之后,dp[start][end] 的状态取决于 dp[start+1][end-1]
接下来我们需要更新一下最大回文字符串长度
如果说当前dp[start][end]为true,且end到start的长度大于之前的maxLen
maxLen = end - start + i;
起始位置begin = start
最后我们返回s.substring(begin, begin + maxLen)
注意:
None
复杂度:
Time Complexity: O(N^2);
Space Complexity : O(N^2);
Code示例:
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
int maxLen = 1, begin = 0;
boolean[][] dp = new boolean[len][len];
char[] arr = s.toCharArray();
for (int end = 0; end < len; end++) {
for (int start = 0; start <= end; start++) {
if (start == end) dp[start][end] = true;
if (arr[start] != arr[end]) dp[start][end] = false;
else {
// 如果当前遍历字符串长度小于4,means 长度为1, 2, 3
// 那我们只用考虑收尾两端是否想等,
// 目前情况是想等, 则返回dp[start][end] = true;
if (end - start + 1 < 4) {
dp[start][end] = true;
} else {
dp[start][end] = dp[start+1][end-1];
}
}
if (dp[start][end] && end - start + 1 > maxLen) {
maxLen = end - start + 1;
begin = start;
}
}
}
return s.substring(begin, begin + maxLen);
}
}