思路:我自己的思路是先求出所有substring,然后依次判断他们是否为回文。然后再所有是回文的substring中选出最长的。这个思路也叫Brute Force。下面给出代码,重要注释已给出:
class Solution {
public String longestPalindrome(String s) {
if(s.length() == 1) return s;
if(s.equals("") || s == null) return "";
int max = 0;
String res = String.valueOf(s.charAt(0));
for(int i = 0; i < s.length()-1; i++){
for(int j = i + 1; j < s.length(); j++){
//get all substrings
if ((j+1)-i <= max) { //如果该substring长度小于当前最大substring长度,直接忽略
continue;
}
if(isPalindrome(s.substring(i,j+1)) == true){
res = s.substring(i,j+1);
max = (j+1)-i;
}
}
}
return res;
}
public boolean isPalindrome(String s){
/*if(s.length() == 1) return true;
if(s.charAt(0) == s.charAt(s.length()-1)){
if(s.length() == 2 || s.length() == 3){
return true;
}else{
return isPalindrome(s.substring(1,s.length()-1));
}
}else{
return false;
} */
int i = 0;
int j = s.length() -1;
while(i < j){
if(s.charAt(i) == s.charAt(j)){
i++;
j--;
}else{
return false;
}
}
return true;
}
}
这边要注意我一开始isPalindrome()方法是用recursion来实现的,这样会报错Time limint exceeded。之后改成遍历的方式就好了。
然而这题是典型的动态规划题(dynamic programming)
我在看完dp解法之后觉得dp有一点像recursion。但是我还不太了解dp,和同学交流后说是dp有些像数学归纳,找规律,这么说好像也有点道理。之后接触更多dp题应该会有更好的理解吧。下面给出dp的官方思路以及解法,重要注释已给出:
class Solution {
public String longestPalindrome(String s) {
if (s == null || "".equals(s)) {
return s;
}
int len = s.length();
String ans = "";
int max = 0;
boolean[][] dp = new boolean[len][len]; //判断substring dp[i][j]是否为回文,将真值存入dp表
for (int j = 0; j < len; j++) { //这两个forloop求的所有子集,不包括空集
for (int i = 0; i <= j; i++) {
boolean judge = s.charAt(i) == s.charAt(j);
if((j+1-i) <= max){ //如果当前substring长度不大于目前已收集到的最大回文长度,先将此sbustring是否为回文存进dp表,然后直接跳出当前循环。因为长度不够,不管是不是回文都没有意义。但是这边依然要求一下此substring是否为回文,然后存入dp表的原因是:之后求别的substring的真值时会用到这个这个substring的真值。
dp[i][j] = j - i > 2 ? dp[i + 1][j - 1] && judge : judge;
continue;
}else{
dp[i][j] = j - i > 2 ? dp[i + 1][j - 1] && judge : judge;
if (dp[i][j]) { //此时已经默认当前substring长度大于max了
max = j - i + 1;
ans = s.substring(i, j + 1);
}
}
}
}
return ans;
}
}
总结
- Time complexity of subString() O(n)
- java BREAK and CONTINUE, break is to break current for loop(e.g., i=1,j=2 to i=2,j=0), continue is to break current case(e.g., i=1, j=2),then continue the next case in this for loop(e.g., i=1,j=3)
- 三目运算符 A? B:C
- compare two string if they are equal: a.equals(b)