647、回文子串
给你一个字符串 s
,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
class Solution {
public int countSubstrings(String s) {
boolean [][]dp=new boolean[s.length()+1][s.length()+1];
//dp[i][j]:表示在[i,j]范围内回文子串的数目
int count=0;
for(int i=s.length()-1;i>=0;i--){
for(int j=i;j<s.length();j++){
if(s.charAt(i)==s.charAt(j)&&(j-i<=1)){
count++;
dp[i][j]=true;
}else if(s.charAt(i)==s.charAt(j)&&dp[i+1][j-1]){
count++;
dp[i][j]=true;
}
}
}
return count;
}
}
213、打家劫舍 II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
把环拆成两个队列,一个是从0到n-1,另一个是从1到n,然后返回两个结果最大的
即:从0到n-1的就把最后一个去掉,不遍历索引为nums.length-1
从1~n 就不遍历索引0 把1当做是第一个
class Solution {
public int rob(int[] nums) {
if(nums.length==1) return nums[0];
if(nums.length==2) return Math.max(nums[0],nums[1]);
int []dp1=new int[nums.length];
int []dp2=new int[nums.length];
//不取最后一个
dp1[0]=nums[0];
dp1[1]=Math.max(nums[0],nums[1]);
for(int i=2;i<=nums.length-2;i++){
dp1[i]=Math.max(dp1[i-1],dp1[i-2]+nums[i]);
}
//不取第一个
dp2[1]=nums[1];//不要写成dp2[0]=nums[1] 这样的话,错位了不好搞
dp2[2]=Math.max(nums[1],nums[2]);
for(int j=3;j<=nums.length-1;j++){
dp2[j]=Math.max(dp2[j-1],dp2[j-2]+nums[j]);
}
return Math.max(dp1[nums.length-2],dp2[nums.length-1]);
}
}