Given a string, your task is to count how many palindromic substrings in this string.
The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.
Example 1:
Input: "abc" Output: 3 Explanation: Three palindromic strings: "a", "b", "c".
Example 2:
Input: "aaa" Output: 6 Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".
Note:
- The input string length won't exceed 1000.
算法:
1.遍历确认法。写一个判断是否正确的子函数。然后主函数里双重for循环,头尾指针夹住substring去判断是不是,用cnt计数。
2.DP。数组定义是dp[i][j]表示s.substring(i, j)是不是palindrome. 转移方程是dp[i][j] = s.charAt(i) == s.charAt(j) && ((j - i < 3) || dp[i + 1][j - 1])。而且注意因为状态转移方程里你需要的是下一个i,上一个j,所以你for循环遍历应该要i往左走,j往右走,同时j还要保证比i大,所以最后表现形式是 for(int i = s.length() - 1; i >= 0; i--) { for (int j = i + 1; j <= s.length(); j++) { ... }}。
细节:1. char和char可以直接==对比,而且char是没有equals方法的,只有Character才有。string.charAt返回的是char不是Character,所以不要对它调用equals()方法,直接==。
2.DP的状态转移方程里那个当字符串长度是1,2,3的特殊情况的时候写法要注意,不写那个调用之前的dp数组会出现ij大小交叉还有指针越界。
实现
1.遍历确认法
class Solution { public int countSubstrings(String s) { if (s == null) { return 0; } int cnt = 0; for (int i = 0; i < s.length(); i++) { for (int j = i + 1; j <= s.length(); j++) { if (isPalindrome(s.substring(i, j))) { cnt++; } } } return cnt; } private boolean isPalindrome(String s) { for (int i = 0, j = s.length() - 1; i < j; i++,j--) { if (s.charAt(i) != s.charAt(j)) { return false; } } return true; } }
2.DP
class Solution { public int countSubstrings(String s) { if (s == null) { return 0; } int n = s.length(); boolean[][] dp = new boolean[n][n]; int cnt = 0; for (int i = n - 1; i >= 0; i--) { for (int j = i; j < n; j++) { dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i <= 2 || dp[i + 1][j - 1]); if (dp[i][j]) { cnt++; } } } return cnt; } }