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.
Solution
本题是一道动态规划问题。我们用动态规划的思想来解答这个问题。
这道题是要找出一个等差数列中有多少子等差数列。那么我们可以提出两个问题。
- 什么是等差数列以及等差数列最少需要几个数
- 一个任意数组有多少个子数组
第一个问题很容易,等差数列必须满足A[N]-A[N-1]==A[N+1]-A[N] 。也就是最少需要三个数。
第二个问题,一个数组有多少子数组呢。
数组 | 子数组个数 |
---|---|
[1] | 1 |
[1,2] | 3 |
[1,2,3] | 6 |
[1,2,3,4] | 10 |
[1,2,3,...,N] | \[x= \cfrac {N(1+N)}{2}\] |
这是一个高中知识,每个人都学过的等差数列的求和公式。这里我们结合上面说的两个问题,假如给定的数组是等差数列的话,那么这个问题的解应该是求数组中长度不小于3的子数组的个数。
如果一个数组不是等差数列,但是它的子数组包含等差数列,这时候我们怎么判断呢?
例如[1,2,3,4,1,2,3,4]
这样的数据不是等差数列,但是子数组是两个等差数列,所以这个数列的子等差数列个数应该是6。也就是说遍历数组的时候如果A[i-1]-A[i-2]==A[i]-A[i-1]那么就按等差求和的方法计算。如果不满足上述条件就清空之前的累加量,从0开始计算累加量。
代码如下:
class Solution { public int numberOfArithmeticSlices(int[] A) { int result=0; int add=0; for (int i = 2; i < A.length; i++) { if(A[i]-A[i-1]==A[i-1]-A[i-2]){ ++add; result+=add; }else{ add=0; } } return result; } }