Question
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, -9The following sequence is not arithmetic.
1, 1, 2, 5, 7A 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.
如果一个数组是由至少3个元素组成,且任意两个连续元素之差都相等,那么我们称它为等差数列。现在给定一个包含N个元素的数组,要求找出该数组中有多少个等差数列
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
第一种方法我们可以找出等差数列长度和其中包含的等差数列个数的关系,假设等差数列长度为n,那么等差数列个数为:(n - 1) * (n - 2) / 2。也就是如果我们得到每一个最长等差数列,那么代入公式即可得到该等差数列包含的等差数列个数
class Solution(object): def numberOfArithmeticSlices(self, A): """ :type A: List[int] :rtype: int """ res = 0 len_consecutive_elements = 2 for index in range(2, len(A)): # 如果该元素属于等差数列,那么等差数列长度+1 if A[index] - A[index - 1] == A[index - 1] - A[index - 2]: len_consecutive_elements += 1 # 如果该元素不属于等差数列,带入公式计算包含等差数列个数,重置len else: if len_consecutive_elements >= 3: res += int((len_consecutive_elements - 1) * (len_consecutive_elements - 2) / 2) len_consecutive_elements = 2 # 带入公式计算最后一个等差数列 res += int((len_consecutive_elements - 1) * (len_consecutive_elements - 2) / 2) return res第二种更快的方法是动态规划。假设我们需要得到[1, 2, 3, 4, 5]的等差数列个数,如果我们能得到它与[1, 2, 3, 4]之间的递推式,那么就很好的解决这个问题了,而事实上它确实是有迹可循的。假设dp[i]为列表前i个数的等差数列个数,递推式为:d[i] = d[i - 1] + j,而j是一个可变量,它的规律如下表
列表 等差数列个数 j [1, 2, 3] 1 1 [1, 2, 3, 4] 3 2 [1, 2, 3, 4, 5] 6 3 [1, 2, 3, 4, 5, 6] 10 4 所以我们在遍历的过程中保存下j即可,代码如下
class Solution(object): def numberOfArithmeticSlices(self, A): """ :type A: List[int] :rtype: int """ if len(A) == 0: return 0 i = 1 dp = [0] * len(A) for index in range(2, len(A)): # 如果属于等差数列则带入递推式,注意更新i(原公式j) if A[index] - A[index - 1] == A[index - 1] - A[index - 2]: dp[index] = dp[index - 1] + i i += 1 # 如果不属于等差数列则代表等差数列个数不发生改变,同时重置i else: dp[index] = dp[index - 1] i = 1 return dp[-1]
本文介绍了一种高效算法来计算数组中等差数列的数量,通过两种方法实现:一种是直接计算等差数列长度并使用数学公式得出结果;另一种是采用动态规划方法,递推计算等差数列的数量。

被折叠的 条评论
为什么被折叠?



