题目链接:
不想戳的看下图
示例:
提示:
解题思路1:
动态规划(dp)
- 在子序列I的基础上可以不连续取值。
- 动态规划——dp[i]中存储的为字典(减小空间损耗,其中存储数组为稀疏数组)。
- dp[i][d] = dp[j][d] + 1, 其中j<i,dp[i][d]表示了以nums[i]结尾的能够构成子序列或伪序列(2个元素)组合个数。
代码如下:
class Solution {
public int numberOfArithmeticSlices(int[] nums) {
int n = nums.length;
int answer = 0;
Map<Long,Integer>[] count = new Map[n];
for(int i=0;i<n;++i){
count[i] = new HashMap<Long,Integer>(); // 重置hashmap
}
for(int i=0;i<n;++i){
for(int j=0;j<i;++j){
Long d = (long) nums[i] -nums[j]; // nums[j]与nums[i]的间隔差
int cur_count = count[j].getOrDefault(d,0);
answer += cur_count; // 更新计数位
count[i].put(d,count[i].getOrDefault(d,0)+cur_count+1); // 更新当前的伪序列&总序列计数
}
}
return answer;
}
}
解题思路2:
哈希表(HashMap)
代码如下:
class Solution {
public int numberOfArithmeticSlices(int[] A) {
int res = 0;
Map<Integer, Integer>[] map = new Map[A.length];
for (int i = 0; i < A.length; i ++) {
map[i] = new HashMap<>();
for (int j = 0; j < i; j ++) {
long d = (long)A[i] - A[j];
if (d > Integer.MAX_VALUE || d <= Integer.MIN_VALUE) continue;
int diff = (int)d;
int c1 = map[i].getOrDefault(diff, 0);
int c2 = map[j].getOrDefault(diff, 0);
res += c2;
map[i].put(diff, c1 + c2 + 1);
}
}
return res;
}
}
小结
本题的解题关键是动态规划,找出状态转移方程,就可以轻松破解!