动态规划
特点:
1.将该问题划分为更小的相似的子问题。
2.求解每个子问题,并将子问题结果保存在一个表中。随用随取,不做重复计算
3.自底向上
回文子串数量 leetcode-647
链接: leetcode-647
public int countSubstrings(String s) {
if(s== null || s==""){
return 0 ;
}
int len = s.length();
int[] dp = new int[len];
int count = 0;
for(int i = 0;i<len;i++){
dp[i] = 1;
count+=1;
for(int j = 0;j<i;j++){
if(s.charAt(i) == s.charAt(j) &&dp[j+1] == 1 ){
dp[j] = 1;
count++;
}else{
dp[j] = 0;
}
}
}
return count;
}
各个时期的dp数组里面的值:倘若从dp[i]到dp[j]中间和两边的值都是1,则表示为一个回文子串
方法2:
int num = 0;
public int countSubstrings(String s) {
for (int i=0; i < s.length(); i++){
count(s, i, i);//回文串长度为奇数
count(s, i, i+1);//回文串长度为偶数
}
return num;
}
public void count(String s, int start, int end){
//以start为中心开始扩散,找到以start为中间值的所有回文子串
while(start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)){
num++;
start--;
end++;
}
}
最长回文字符串 leetcode- 5
链接: leetcode- 5 .
public String longestPalindrome(String s) {
if(s==null||s==""){
return "";
}
// 定义两个指针
int[] range = new int[2];
char[] strChar = s.toCharArray();
for(int i = 0;i<s.length();i++){
i = getLongestPalindrome(strChar,i,range);
}
return s.substring(range[0],range[1]+1);
}
public int getLongestPalindrome(char[] strChar , int low,int[] range){
int high = low;
// 当下一个与当前相同时在进行扩展找下一位
while(high<strChar.length-1 && strChar[low] == strChar[high+1]){
high++;
}
//定位出的中间位置的最后一个字符,如果在下一个while后面赋值 则会出现回文字符串变短情况 如 bananas
int ans = high;
while(low > 0&&high<strChar.length-1 && strChar[low-1] == strChar[high+1] ){
low--;
high++;
}
if(high-low>range[1]-range[0]){
range[1] = high;
range[0] = low;
}
return ans;
}