leetcode 413. Arithmetic Slices ( Python )

485 阅读22分钟

描述

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.

解析

根据题意,可以暴力破解,遍历所有的组合,然后判断每个组合是否是等差数列,时间复杂度为 O(N^3),这种方法肯定是超时的,空间复杂度为 O(1)。

解答

class Solution(object):
    def numberOfArithmeticSlices(self, A):
        """
        :type A: List[int]
        :rtype: int
        """
        def isArithmetic(A,start,end):
            s = A[start:end+1]
            for i in range(len(s)-2):
                if s[i]-s[i+1] == s[i+1]-s[i+2]:
                    continue
                else:
                    print(0)
                    return 0
            return 1

        N = len(A)
        count = 0
        for i in range(N-2):
            for j in range(i+1,N):
                if j-i>=2:
                    count += isArithmetic(A,i,j)
        return count

    	      
		

运行结果

Runtime: Time Limit Exceeded

解析

根据题意,可以优化暴力破解,遍历所有的组合,然后判断每个组合的前三个数是否是等差数列,如果是就计数,并继续进行下一个组合,如果不是则直接进行下一个组合的判断,时间复杂度为 O(N^2),空间复杂度为 O(1)。

解答

class Solution(object):
    def numberOfArithmeticSlices(self, A):
        """
        :type A: List[int]
        :rtype: int
        """
        N = len(A)
        count = 0
        for i in range(N-2):
            d = A[i+1]-A[i]
            for j in range(i+1,N-1):
                if d==A[j+1]-A[j]:
                    count+=1
                else:
                    break
        return count        	      
		

运行结果

Runtime: 168 ms, faster than 5.69% of Python online submissions for Arithmetic Slices.
Memory Usage: 11.8 MB, less than 93.10% of Python online submissions for Arithmetic Slices.

解析

根据题意,可以使用动态规划,从上一种方法中其实可以隐约看出,一个长的等差数列包含的所有等差数列的数量是有规律的,

数组等差数列的数目与上一数组的等差数列数目比较
1 2 311
1 2 3 432
1 2 3 4 563
1 2 3 4 5 6104

观察就能发现两个等差数列数目之差(表格第三列)就是[1,2, 3, 4, 5……]这个序列,因此每次增加一个等差数列的元素,总的等差数列的数目就会增加[1,2,3,4,5……]中对应的数值。 设置一个计数器,遍历所有的元素,按照上述规律对计数器进行操作即可,时间复杂度为 O(N),空间复杂度为 O(1)。

解答

class Solution(object):
    def numberOfArithmeticSlices(self, A):
        """
        :type A: List[int]
        :rtype: int
        """
        N = len(A)
        count = 0
        tmp = 0
        for i in range(N-2):
            if A[i+2]-A[i+1] == A[i+1]-A[i]:
                tmp+=1
                count+=tmp
            else:
                tmp = 0
        return count    	      
		

运行结果

Runtime: 20 ms, faster than 91.79% of Python online submissions for Arithmetic Slices.
Memory Usage: 12 MB, less than 64.65% of Python online submissions for Arithmetic Slices.

每日格言:人生中出现的一切,都无法拥有,只能经历。

请作者吃梨 支付宝

支付宝

微信

微信