[LeetCode] Arithmetic Slices

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)。

代码中注释了造成超时的表达式。

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A)
    {
        int res = 0;
        if (A.size() < 3)
            return res;
        for (int i = 0; i < A.size() - 2; i++)
        {
            for (int j = i + 2; j < A.size(); j++)
            {
                int cnt = 0;
                int tmp = A[i + 1] - A[i];
                for (int k = i + 1; k <= j; k++)
                {
                    /* Using this expression causes TLE  
                    if (A[k] - A[k - 1] == tmp)
                        cnt++;
                    */
                    if (A[k] - A[k - 1] != tmp)
                        break;
                    cnt++;
                }
                if (cnt == j - i)
                    res++;
            }
        }
        return res;
    }
};
// 84 ms

第一次使用了注释的代码,结果造成TLE。通过验证得出算法没问题,就是时间复杂度极高导致不能AC

第二次使用break提前挑出循环,减少了一丢丢计算量。成功AC

———————————————————————————————————————————————————————

通过了解蛮力算法过程,确实重复了太多次判断,感觉使用DP也可以求解。下次想通了再更新~~

感觉自己对dp还是了解地不够透彻,先贴上DP的答案,分析如下:

1、先对一些边界进行判断。

2、构造dp数组,第i个元素表示到A[i]为止的切片数量

3、dp[i] = dp[i - 1] + 1来更新dp数组

4、把dp[i]的值累加到结果中

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        int n = A.size();
        if (n < 3)
            return 0;
        vector<int> dp(n, 0);
        if (A[2] - A[1] == A[1] - A[0])
            dp[2] = 1;
        int res = dp[2];
        for (int i = 3; i < n; i++) {
            if (A[i] - A[i - 1] == A[i - 1] - A[i - 2])
                dp[i] = dp[i - 1] + 1;
            res += dp[i];
        }
        return res;
    }
};
// 4 ms
原文地址:https://www.cnblogs.com/immjc/p/8323747.html