leecode---05---字符串,回文,动态规划---查找最长的回文子串

 
题意
目的是找到最长的回文子串,必须记录好子串的起点,子串的长度这两个参量,然后将子串返回。
 
 
分析
方法1:时间换空间
对于每个点,做两个指针往两边跑,跑的过程中判断是否刷新最长回文的长度。遍历的过程中注意区分一下奇数偶数就可以了,区分奇偶数的方式就是指针要么同时从一个数走,要么同时从当前数和后一个数字走起。
 
方法二:动态规划
空间换时间的类型
 
代码

 
class Solution {
    
    int max;
    int start;//因为最后要返回结果所以要记录最长回文子串的开始位置
    
    public String longestPalindrome(String s) {
        if (s == null || s.length() == 0) return null;
        if (s.length() == 1) return s;
        
        //遍历的时候分成奇数和偶数,奇数对应的位置相同,偶数的话就是两端相同
        for (int i = 0; i < s.length(); i++) {
            getMaxPalindrome(s,i,i);
            getMaxPalindrome(s,i,i+1);
        }
        
        //最后返回结果值
        return s.substring(start,start+max);
    }
    
    //写一个函数,更新从Left往左以及right往右的最大回文
    public void getMaxPalindrome(String s,int left,int right) {
        //如果左右相等并且没有超出边界的话就继续移动
        while (left >=0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        //循环的结果就是左右两边的参数是不相等的
        if (max < right - left + 1 -2) {
            start = left + 1;
            max = right - left - 1;
        }
    }
}
 
 

空间换时间的方式计算
假设dp[i][j]表示从i到j个字符串是回文字符串。
那么 dp[i][j] = dp[i+1][j-1] && (s.charAt(i) == s.charAt(j))
其中dp[i +1][j-1]涉及到i和j.可能的极限情况就是 i+1==j-1或者两个参数值相邻。那么这就涉及到初始化。
1.dp[i][i]==true
2.dp[i][i+1] == true
 
第一种动态规划写法是错误的:
class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() == 0) return null;
        if (s.length() ==1) return s;
        
        String result = null;
        int max = 1;
        int[][] dp = new int[s.length()][s.length()];
        
        //初始化,相邻状态和相等状态
        for (int i = 0; i < s.length(); i++) {
            dp[i][i] = 1;
            result = String.valueOf(s.charAt(i));
        }
        for (int i = 0; i < s.length() - 1; i++) {
            if (s.charAt(i) == s.charAt(i + 1)) {dp[i][i + 1] = 1;max = 2;result = s.substring(i,i+2);}
        }
        
        //这边的写法是错误的!!!假设从i=0开始,j从2开始往右边跑直到4。但是一开始bcb的dp值是0,因为是从左往右遍历的,所以在判断abcba的时候虽然头尾都是相等的,但是bcb的dp值是0,也就是说abcba也是0,所以不能够从左往右遍历!!!!
        //然后进行动态规划判断普通情况dp[i][j]从i到j的值
        //1.第一层循环的终点是左边在length - 2的位置
        //2.第二层循环的点j从i+2开始,因为相邻和相等情况之前判断过了
        //3.判断i和j指向的值是否是相等的,如果相等更新下最大值
        for (int i = 0; i < s.length() -2; i++) {
            for (int j = i + 2; j < s.length(); j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i + 1][j - 1];
                    if (dp[i][j] == 1 && (j - i + 1) > max) {
                        max = j - i + 1;
                        result = s.substring(i,j+1);
                    }
                } else {
                    dp[i][j] = 0;
                }
            }
        }
        
        //返回结果
        return result;
    }
}
 
 

 
动态规划的正确解法,应该按照长度大小来设置普通情况下的字符串长度。
 
class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() == 0) return null;
        if (s.length() ==1) return s;
        
        String result = null;
        int max = 1;
        int[][] dp = new int[s.length()][s.length()];
        
        //初始化,相邻状态和相等状态
        for (int i = 0; i < s.length(); i++) {
            dp[i][i] = 1;
            result = String.valueOf(s.charAt(i));
        }
        for (int i = 0; i < s.length() - 1; i++) {
            if (s.charAt(i) == s.charAt(i + 1)) {dp[i][i + 1] = 1;max = 2;result = s.substring(i,i+2);}
        }
        
        //然后进行动态规划判断普通情况dp[i][j]从i到j的值
        //必须从长度开始判断,长度从3开始处理
        for (int l = 3; l <= s.length(); l++) {
            for (int i = 0; i + l - 1 < s.length(); i++) {
                int j = i + l - 1;//就是加上长度之后的右边的值
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i + 1][j - 1];
                    if (dp[i][j] == 1 && l > max) {
                        max = l;
                        result = s.substring(i,j + 1);
                    }
                } else {
                    dp[i][j] = 0;
                }
            }
        }
        
        //返回结果
        return result;
    }
}
posted @ 2018-04-17 10:50  buptyuhanwen  阅读(440)  评论(0编辑  收藏  举报