PS:说好的一天一道leetcode,前天停电,今天打算补3道,昨天其实还写了一道,太简单,就没有往博客上放。
A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.
For example, these are arithmetic sequence:
1, 3, 5, 7, 9 7, 7, 7, 7 3, -1, -5, -9
The following sequence is not arithmetic.
1, 1, 2, 5, 7
A zero-indexed array A consisting of N numbers is given. A slice of that array is any pair of integers (P, Q) such that 0 <= P < Q < N.
A slice (P, Q) of array A is called arithmetic if the sequence:
A[P], A[p + 1], ..., A[Q - 1], A[Q] is arithmetic. In particular, this means that P + 1 < Q.
The function should return the number of arithmetic slices in the array A.
Example:
A = [1, 2, 3, 4] return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4] itself.
这个题目死长死长的,其实就是说,让你计算一个数组里面有多少个算数级数,就是等差数列,长度最少为3,最长为数组长度,然后就没有了。
1.先来暴力解法,我在本子上写好伪代码,然后照着敲上去,一次AC。就是效率有点低。
代码如下:
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& A) {
if(A.size() < 3)
return 0;
const int n = A.size();
int count = 0;
for(int k=3; k<=n; ++k){
for(int i=0; i<=n-k; ++i){
int s = A[i+1] - A[i];
int j = 2;
while(j < k){
if(A[i+j] - A[i+j-1] != s)
break;
++j;
}
if(j == k && A[i+j-1] - A[i+j-2] == s)
++count;
}
}
return count;
}
};
2.DP
其实DP的思想很简单,可是我开始就是没有想到,也往DP方向想了,但是没有思路。
比如: 1 2 3 4 5
下标i从0开始,当i为2时,初始状态有一组算术级数,123。
当i为3时,算数级数有:1234,234
当i为4时,算数级数有:12345,2345,345
通过上面规律不难发现,每次新增加一个元素,都是先在已有元素的基础上append上去,再加上自己新带来的长度为3的一组级数。
所以,dp[i] = dp[i-1] + 1,可以通过前期计算过的子问题来解决新问题,这不就是动态规划吗?
代码如下:
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& A) {
if(A.size() < 3)
return 0;
const int n = A.size();
int count = 0;
vector<int> dp(n, 0);
for(int i=2; i<n; ++i){
if(A[i] - A[i-1] == A[i-1] - A[i-2])
dp[i] += dp[i-1] + 1;
count += dp[i];
}
return count;
}
};