[DP]413. Arithmetic Slices

来源:互联网 发布:js动态修改style属性 编辑:程序博客网 时间:2024/06/06 16:34
题目:

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.


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.


题目分析:

1、根据题目定义,一个等差数列的长度至少为3。对于给出的数列,我们需要统计其中包含的等差数列的数量。

2、很明显对于长度为0[NULL]、1、2的数列,其不可能包含等差数列。对于长度大于等于3的数列,若其整个为一个等差数列,那么它所包含的等差数列数量N计算方法为(假设起长度为n ≥ 3):N = 1 + 2 + 3 + 4 + ……+ (n - 2)= (n - 1)(n - 2)/ 2,原理为分别其中统计长度为3、4、5……n的等差数列组合即可。对于长度为n ≥ 3但并非整个为等差数列的数列而言,为了统计其中包含的等差数列数量,我们只需要求出其中所包含的最长等差数列的个数即可,也就是统计范围内的数列并不能将两端的数加入以生成更长的等差数列。如对于数列A[1、2、3、4、9、5、1、-3、9]而言,它包含两个最长等差数列[1、2、3、4]和[9、5、1、-3],分别包含3个等差子数列,那么整个数列A而言,它所包含的所有等差数列和为3 + 3 = 6个。

3、现在面临的问题是如何去找出数列中的所有最长等差数列。很明显任意两个不同的最长等差数列并不会相互重合,否则这两个数列可以合并。既然不会重合,那么我们就可以对数列A进行一次遍历来解决,只需要设置两个指示头尾下标的参数 start 和 end,初始化为0、1;若A[end + 1] - A[end] = A[end] - A[end - 1], 那么说明A[end + 1]满足前面数列的公差,则end ++继续判断,直至等式不成立表示A[end + 1]不满足前面等差数列的公差,则结束前面的最长等差数列的统计,如果你n = end - start + 1 ≥ 3,则找到了一个最长等差数列,计入统计,接下来开始下一次统计,即start = end, end += 1。

4、此题中采用另一种统计方法,即先对数列A作出预处理,新建数列sub统计每两个相邻数的差值,则在3中的判决等式不需要调用三个数列值,只需要判断sub中相邻两个数是否相等即可,且在统计过程中取消两个参数start和end,采用一个指示变量loc和计数变量countn即可。


代码:

class Solution {public:    int numberOfArithmeticSlices(vector<int>& A) {        if(A.size() < 3)            return 0;        int sub[A.size() - 1];        for(int i = 0; i < A.size() - 1; i++){            sub[i] = A[i + 1] - A[i];        }        int count = 0;        int loc = 0;        while(loc < A.size() - 1){            int subn = sub[loc];            int countn = 1;            while(loc < A.size() - 1){                if(sub[loc] == subn)                    countn ++;                else break;                loc ++;            }            if(countn >= 2){                count += (countn-2)*(countn-1)/2;                }            //loc ++;     //not need        }        return count;    }};

0 0
原创粉丝点击