413. Arithmetic Slices -Medium

来源:互联网 发布:苹果版戒色软件 编辑:程序博客网 时间:2024/06/05 05:20

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, 97, 7, 7, 73, -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.

如果一个数组是由至少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]
0 0
原创粉丝点击