暴力算法
定义一个函数isArithmetic(i,j,nums)用来判断nums下标i到j的子数组是否满足等差数列
通过双重for循环判断所有长度大于等于3的子数组是否满足等差数列
下边有个优化的点就是只要子数组i到j已经不满足等差数列了 那么它后边的i到j+1都不用看了直接break退出这次大循环
var numberOfArithmeticSlices = function(nums) {
if(nums.length<3){return 0}
let n = nums.length
let res = 0
for(let i =0;i<n-2;i++){
for(let j =i+2;j<n;j++){
if(isArithmetic(i,j,nums)){
res++
}else{
// 优化的点
break
}
}
}
function isArithmetic(i,j,nums){
var smallArr = nums.slice(i,j+1)
let diff = smallArr[1]-smallArr[0]
for(let i =2;i<smallArr.length;i++){
if((smallArr[i]-smallArr[i-1])!==diff){
return false
}
}
return true
}
return res
};
动态规划
dp[i]代表以下标i为结尾的等差数列有几个
只要nums[i]-nums[i-1]==nums[i-1]-nums[i-2]
就说明nums[i-2] nums[i-1] nums[i]是个等差数列
这个时候dp[i] = dp[i-1]+1
这个dp[i-1]和+1是哪来的呢?
+1就是nums[i-2] nums[i-1] nums[i]构成的新等差数列
dp[i-1]就是之前下标i-1为结尾的等差数列再补上nums[i]所组成的新等差数列
var numberOfArithmeticSlices = function(nums) {
let n = nums.length
let dp = new Array(n) // dp[i]代表以下标i为结尾的等差数列有几个
dp[0]=0
dp[1]=0
for(let i =2;i<n;i++){
if(nums[i]-nums[i-1]==nums[i-1]-nums[i-2]){
dp[i] = dp[i-1]+1
}else{
dp[i]=0
}
}
let res = 0
for(let i =0;i<n;i++){
res += dp[i]
}
return res
};