446. Arithmetic Slices II

来源:互联网 发布:郝海东网络直播视频 编辑:程序博客网 时间:2024/06/07 09:21

题目:A sequence of numbers is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.A zero-indexed array A consisting of N numbers is given. A subsequence slice of that array is any sequence of integers (P0, P1, ..., Pk) such that 0 ≤ P0 < P1 < ... < Pk < N. subsequence slice (P0, P1, ..., Pk) of array A is called arithmetic if the sequence A[P0], A[P1], ..., A[Pk-1], A[Pk] is arithmetic. In particular, this means that k ≥ 2. The function should return the number of arithmetic subsequence slices in the array A.

The input contains N integers. Every integer is in the range of -231 and 231-1 and 0 ≤ N ≤ 1000. The output is guaranteed to be less than 231-1.

原题目太长了,大意就是定义了等差数列,是一个长度大于等于3的数列,给定一个数列,找出里面等差数列的个数,等差数列的长度大于等于3就可以,数列可以不连续。注意整数的范围是 -231 到 231-1。给定数列A的长度N范围是0 ≤ N ≤ 1000。


思路:之前做了一道题413 Arthmetic Slices,那道题严格要求等差数列是连续的,于是用一个一维数组dp[n]表示以第n个数字为结尾的等差数列个数。初始化dp全为0。如果A[2]-A[1]=A[1]-A[0],那么dp[2] = 1。令i从3遍历到n,检查A[i]-A[i-1]和A[i-1]-A[i-2]是否相等,如果不相等,那么dp[i]不改变还是0,因为第A[I]和A[I-1]、A[I-2]连续的3个数不能构成等差数列。如果相等,那么dp[i] = dp[i--1]+1,之前以i-1为结尾的数列再加上A[i]又能构成等差数列,所以dp[i]比dp[i-1]多1。最后将dp的所有数字相加就能得到结果。

这道题与上面那一题的差别是数列可以不连续,也就是每个数字可以和前面不同的数字组成等差数列,那就会有不同的差,所以需要在上一题的基础上给dp增加一维记录差。dp[i][diff]表示以A[i]结尾,与前面数字差别为diff的数列个数。i从0遍历到n,j从0遍历到i,计算每一个A[i]-A[j]的值为diff,那么以i为结尾,diff为差的数列个数就加1,如果dp[j][diff]不为0,说明以j为结尾,diff为差的数列存在,这时候就至少有3个数可以组成等差数列(i,j,j前面与j差为diff的数),以j为结尾,diff为差的每一个等差数列再加上A[i]之后,都可以组成新的等差数列,所以dp[i][diff] = dp[i][diff] + dp[j][diff]。最后将所有的dp[i][diff]相加就得到结果了。特别注意这题整数的范围 -231 到 231-1,所以要用long型。


class Solution {public:    int numberOfArithmeticSlices(vector<int>& A) {        int n = A.size();        vector<unordered_map<int,int> > dp(n);//长度为n的vector,每一个值是不同的diff对应的数列个数        int res = 0;        for(int i = 0; i < n; ++i)        {            for(int j = 0; j < i; ++j)            {                long diff = (long)A[i] - (long)A[j];                if(diff > INT_MAX || diff < INT_MIN)//判断是否越界                    continue;                diff = (int)diff;                if(!dp[i].count(diff))//空处理                    dp[i][diff] = 0;                dp[i][diff]++;                if(dp[j].count(diff) != 0)//前面有数字能组成等差数列                {                    res += dp[j][diff];//累加结果                    dp[i][diff] += dp[j][diff];//状态转移                }            }        }        return res;    }};



0 0
原创粉丝点击