import java.util.*; /** * NC353 回文子串的数量 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return int整型 */ public int Substrings (String str) { // return solution1(str); // return solution2(str); return solution3(str); } /** * 模拟法 * @param str * @return */ private int solution1(String str){ int count = 0; for(int i=0; i<str.length(); i++){ for(int j=0; j<=i; j++){ if(str.charAt(j) == str.charAt(i)){ if(isPalindrome(str.substring(j,i+1))){ count++; } } } } return count; } /** * 动态规划 * * dp[j][i]表示子串(从j到i)是否为回文串 * * { dp[j+1][i-1] , str.charAt(j) == str.charAt(i) * dp[j][i] = { * { false , str.charAt(j) != str.charAt(i) * * @param str * @return */ private int solution2(String str){ int len = str.length(); boolean[][] dp = new boolean[len][len]; int count = 0; for(int i=0; i<len; i++){ for(int j=0; j<=i; j++){ if(str.charAt(j) == str.charAt(i)){ if(i-j <= 1){ count++; dp[j][i] = true; }else{ if(dp[j+1][i-1]){ count++; dp[j][i] = true; } } } } } return count; } /** * 双指针中心扩展法 * @param str * @return */ private int solution3(String str){ int len = str.length(); int count = 0; for(int i=0; i<len; i++){ // 奇回文 count += expand(str, i, i); // 偶回文 count += expand(str, i, i+1); } return count; } /** * 中心扩展法 * @param str * @param i * @param j * @return */ private int expand(String str, int i, int j){ int count = 0; while(0<=i && j<str.length() && str.charAt(i--)==str.charAt(j++)){ count++; } return count; } /** * 是否回文串 * 比checkPalindrome()效率高 * @param str * @return */ private boolean isPalindrome(String str){ for(int i=0,j=str.length()-1; i<=j; i++,j--){ if(str.charAt(i) != str.charAt(j)){ return false; } } return true; } /** * 校验回文串 * @param str * @return */ private boolean checkPalindrome(String str){ StringBuilder sb = new StringBuilder(str); return sb.reverse().toString().equals(str); } }