LeetCode413. Arithmetic Slices题解

本文介绍了一种使用动态规划解决特定数组中算术片段计数问题的方法。通过分析数组元素间的差值来确定算术片段的存在,并计算出片段的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 题目描述

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.

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.

【翻译过来】:题目首先定义了arithmetic的概念:相邻的两个元素的差值相同,这样的数组就是arithmetic的。一定要注意是相邻的这个条件,如果不注意这个条件,会对后面的分析带来很大的困惑。
接着题目给出了一个数组,需要我们求出这个数组包含的arithmetic片段的数目。所谓包含的arithmetic片段,其实就是原数组的若干子集的数目,这些子集需要满足arithmetic的性质即可。

2. 样例

arithmetic的数组:

1, 3, 5, 7, 9
7, 7, 7, 7
3, -1, -5, -9

非arithmetic的数组:

1, 1, 2, 5, 7

输入输出样例:

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.

3. 分析

判断arithmetic的特性以及子集的数目,很明显的动态规划的题型。经过分析我们知道,所谓arithmetic的片段不过是原数组的相邻的子集而已,我们只要求出原数组下arithmetic的子数组个数既是答案。
因此,我们可以从前两个元素开始判断,计算它们的差值difference,然后循环开始遍历。
这里我们的思路是:每当出现一个新的元素满足差值与difference相同,该部分的子集长度就增长一个,例如:
【上一次arithmetic片段】:

1,3,5

片段是【1,3,5】,counter = 1
【增加一个满足的元素】:

1,3,5,7

片段是【1,3,5】,【1,3,5,7】,【3,5,7】,counter = 1 + 2 = 3
即:当新增的元素满足difference的值currentCounter一直满足等差数列的增长:1,2,3……。这是因为counterCurrent代表的是以当前新增元素结尾的arithmetic子片段个数。每个新增元素都会产生新的arithmetic子片段,所以总和counter每一次都会加上counterCurrent
这里写图片描述

4. 源码

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        if (A.size() <= 2) {
            return 0;
        }
        int counter = 0;
        int currentCounter = 0;
        int difference = A[0] - A[1];
        for (int i = 1; i < (int)A.size() - 1; i++) {
            if ((A[i] - A[i+1]) == difference) {
                currentCounter++;
            }
            else {
                currentCounter= 0;
                difference = A[i] - A[i+1];
            }
            counter += currentCounter;
        }
        return counter;
    }
};

5. 心得

动态规划的算法比较难想而且理解起来比较吃力,本题主要是currentCounter代表的是当前以新增元素结尾的arithmetic子片段个数。因为每一次新增元素产生的子片段都是新的,总数里面都要加上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值