(M)Dynamic Programming: 413. Arithmetic Slices

来源:互联网 发布:九鼎彩社用的软件 编辑:程序博客网 时间:2024/06/09 20:53

先写出几个来看看,找找规律:

A = {1,2,3,4,5,6,7}

新建一个数组res,res[i]保存0~i这些数里的等差数列个数,那么:

res[0] = 0;

res[1] = 0;

res[2] = {1,2,3}

res[3] = {1,2,3} + {2,3,4} + {1,2,3,4}

res[4] = {1,2,3} + {2,3,4} + {1,2,3,4} + {3,4,5} + {2,3,4,5} + {1,2,3,4,5}

...

可以发现,res[i]是res[i - 1]的结果加上包含了A[i]的等差数列个数。那就很好求了:

class Solution {public:    int numberOfArithmeticSlices(vector<int>& A) {        if(A.size() < 3)            return 0;        vector<int> res(A.size(), 0);        for(int i = 2; i < A.size(); ++i)        {            res[i] = res[i - 1] + countArithmic(A, 0, i);        }        return res[A.size() - 1];    }    int countArithmic(vector<int>& A, int start, int end)  //包含A[end]的等差数列个数,就是由A[end]一位一位往前找,遇到不能构成等差数列的就break    {        if(end - start + 1 < 3)            return 0;        int cha = A[end] - A[end - 1];        int res = 0;        for(int i = end - 1; i > start; --i)        {            if(A[i] - A[i - 1] == cha)                res++;            else                break;        }        return res;    }};
但是!这样还是太麻烦,还可以简化的。countArithmic这个函数,往前一个一个的找,这样会有很多重复计算,但是显然,如果A[i]能和前面的两个数构成等差数列,那么也能和他们前面的数构成等差数列。如

1,2,3,4,5

4能和1,2,3构成等差数列,5能和3,4构成等差数列,那么5也能和3,4前面的构成等差数列。所以以5结尾的等差数列是以4结尾的等差数列加上{3,4,5}。

所以代码可以改进成这样:设置一个dp数组,dp[i]存的是以[i]结尾的等差数列个数,那么dp[i] = dp[i - 1] + 1;

class Solution {        // 2nd round        date: 2016-10-15        location: Vista Del Lago III Apartementpublic:    int numberOfArithmeticSlices(vector<int>& A) {        if (A.size() < 3)   return 0;        vector<int> dp(A.size(), 0);        int res = 0;        for (int i = 2; i < A.size(); i ++) {            if (A[i] - A[i - 1] == A[i - 1] - A[i - 2])                dp[i] = dp[i - 1] + 1;            res += dp[i];        }        return res;    }};


原创粉丝点击