LeetCode #413: Arithmetic Slices

Problem

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.

题意

输入一个数组,求出该数组中连续的等差数列的数量。

注意

  1. 等差数列的最短长度为3,对于长度大于3的等差数列,要计算其子集(子序列)数量。
  2. 只有当连续的序列构成等差关系时,才满足条件。例如,[1, 2, 3, 4, 5]中,[1,3 5]并不是一个符合要求的解。

分析&思路

依然是一道被放在动态规划分类下的题目,但是并没有想到动规的解法QAQ···
按照自己的思路来:

  • 首先找出整个数组中所有满足条件的“长等差数列”(例如,[2, 1, 2, 3, 4, 4, 4, 4]中,所谓的“长等差数列”有[1, 2, 3, 4],[4, 4, 4, 4],而忽略掉[1, 2, 3]、[2, 3, 4]、[4, 4, 4]这样的可视为某个“长等差数列”的子集的等差数列)对于每个满足条件的等差数列,都只记录它的最大长度。

  • 将每个“长等差数列”的长度记录在一个vector<int> sliceLen

  • 对于长度为i的等差数列,其子集数量为i - 3 + 1(自行找规律即可,证明略)

  • 最后的结果就是遍历sliceLen,求子集数量的和即可。

Code

//Runtime: 6ms
//时间复杂度:O(n),空间复杂度:O(n)
class Solution {
private:
    //计算长度为sliceLen的等差数列的子等差数列的数量
    int _numOfSubslice(int sliceLen){
        int result = 0;
        for (int i = 1; i <= sliceLen - 3 + 1; i++){
            result += i;
        }

        return result;
    }
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        if (A.empty() || A.size() < 3)  return 0;
        //计算每个A[i+1]-A[i]
        vector<int> diff;
        diff.resize(A.size() - 1);
        for (int i = 0; i < A.size() - 1; i++)
            diff[i] = A[i+1] - A[i];
        
        //sliceLen存储所有“长等差数列”的长度
        vector<int> sliceLen;
        for (int i = 0; i < diff.size(); i++){
            //初始长度为2
            int local_sliceLen = 2;
            //如果连续的两个diff相等,则意味着开始构成了等差数列
            while((i < diff.size() - 1) && (diff[i] == diff[i+1])){
                i++;
                local_sliceLen++;
            }
            if (local_sliceLen >= 3)    sliceLen.push_back(local_sliceLen);
        }

        int result = 0;
        for (int i = 0; i < sliceLen.size(); i++)
            result += _numOfSubslice(sliceLen[i]);
        
        return result;
    }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 远方 撑着油纸伞的姑娘 寻找着登船的港口 判不清方向,靠不近彼岸 像是无悲无喜无心伤的石头 那些梦 都随着潺潺流水...
    何夏陌舟阅读 411评论 0 0
  • 昨晚做了一个甜甜的梦,梦到自己所有的好朋友都在身边,和她们一块聊天,然后我看着她们暖暖的笑了。继而我睁开了眼...
    想飞的小妮子阅读 134评论 1 0
  • 今天5月1日,星期一,距离高考还有36天。时间一天紧似一天啦。但不管怎么紧,只要一切有序,一切有计划运转,人就不会...
    耘心阅读 225评论 0 0
  • 有这样一段话 现实中人们都不是互相等待的 你等的人 也许在万水千山之外惊鸿一瞥遇见了 那个人却不是在等你 也或许那...
    敢说真话的妖精阅读 471评论 1 2