leetcode 647.回文子串

给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。

示例 1:

输入: "abc"
输出: 3
解释: 三个回文子串: "a", "b", "c".

示例 2:

输入: "aaa"
输出: 6
说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa".

注意:

  1. 输入的字符串长度不会超过1000。

 第一种做法:

关于回文最先想到的还是动态规划,用一个dp二维数组判断,一个回文子串前后加上两个相同的字母还是回文子串。

class Solution {
    public int countSubstrings(String s) {
        int len = s.length();
        int count = len;
        int[][] flag = new int[len][len];
        for(int i = 0;i < len - 1;i++){
            flag[i][i] = 1;
            if(s.charAt(i) == s.charAt(i + 1)){
                flag[i][i + 1] = 1;
                count++;
            }            
        }
        for(int i = len - 2;i >= 0;i--){
            for(int j = i + 1;j < len;j++){
                if(s.charAt(i) == s.charAt(j) && flag[i + 1][j - 1] == 1){
                    flag[i][j] = 1; 
                    count++;
                }
            }
        }
        
        return count;
    }
}

不过空间O(n^2)太浪费了。

第二种做法

中心扩展,其实也就是从回文串的中间开始算,用两个指针向两边计算,如果字母一样的话,就还是回文串,很好理解。

class Solution {
    public int countSubstrings(String s) {
        int count = 0;
        
        for (int i = 0; i < s.length(); i += 1) {
            count += countSubstringsImpl(s, i, i);
            count += countSubstringsImpl(s, i, i + 1);
        }
    
        
        return count;
    }
    
    public int countSubstringsImpl(String s, int l, int r) {
        int count = 0;
        while(l >= 0 && r < s.length() && s.charAt(l--) == s.charAt(r++)) {
            count += 1;
        }
        
        return count;
    }
}

 

你可能感兴趣的:(leetcode,双指针,动态规划)