题目1
题解
差分+计数
以数列 [1,2,3,4,6] 为例:
[1,2]的差为1,则差值d=1,此时增加值t=0
[2,3]的差也为1,增加值t=1,结果+1(发现了[1,2,3]这个等差数列)
[3,4]的差也为1,增加值t=2,结果+2(发现了[2,3,4]和[1,2,3,4]两个等差数列)
[4,6]的差为2,增加值t=0,结果不变
最终结果res=3
class Solution {
public int numberOfArithmeticSlices(int[] nums) {
int n=nums.length;
if(n<3)
return 0;
int d=nums[1]-nums[0],res=0,t=0;
for(int i=2;i<n;i++){
if(nums[i]-nums[i-1]==d){
t++;
}
else{
d=nums[i]-nums[i-1];
t=0;
}
res+=t;
}
return res;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
题目2
题解
- 状态定义:dp[i] 表示字符串 s 的前 i 个字符 s[1…i] 的解码方法数
- 状态转移方程:
(1)只使用一个字符,即s[i],如果s[i]!=0:dp[i] = dp[i-1]
;
(2)使用两个字符,s[i-1]和s[i],如果s[i]!=0&&组成整数<=26:dp[i] = dp[i-2]
上面两个状态方程累加,得到dp[i]的值 - 初始条件:dp[0]=1,空字符串有一种解码方法
- 返回值:dp[n]
class Solution {
public int numDecodings(String s) {
int n=s.length();
int[] dp=new int[n+1];
dp[0]=1;
for(int i=1;i<=s.length();i++){
//只使用一个字符
if(s.charAt(i-1)!='0')
dp[i]+=dp[i-1];
//使用两个字符
if(i>1&&s.charAt(i-2)!='0'&&((s.charAt(i-2)-'0')*10+(s.charAt(i-1)-'0'))<=26)
dp[i]+=dp[i-2];
}
return dp[n];
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n),亦可以使用滚动数组将空间复杂度降至O(1)