413. Arithmetic Slices

本文介绍了一道LeetCode上的等差数列切片问题,并提供了两种解决方案:一种是暴力解法,另一种是更高效的动态规划方法。通过对示例的详细解析,帮助读者理解如何计算数组中等差数列的数量。

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

PS:说好的一天一道leetcode,前天停电,今天打算补3道,昨天其实还写了一道,太简单,就没有往博客上放。

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.

这个题目死长死长的,其实就是说,让你计算一个数组里面有多少个算数级数,就是等差数列,长度最少为3,最长为数组长度,然后就没有了。

1.先来暴力解法,我在本子上写好伪代码,然后照着敲上去,一次AC。就是效率有点低。

代码如下:

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        if(A.size() < 3)
            return 0;
        
        const int n = A.size();
        int count = 0;
        
        for(int k=3; k<=n; ++k){
            for(int i=0; i<=n-k; ++i){
                int s = A[i+1] - A[i];
                int j = 2;
                while(j < k){
                    if(A[i+j] - A[i+j-1] != s)
                        break;
                    ++j;
                }
                if(j == k && A[i+j-1] - A[i+j-2] == s)
                    ++count;
            }
        }
        return count;
    }
};



2.DP

其实DP的思想很简单,可是我开始就是没有想到,也往DP方向想了,但是没有思路。

比如: 1 2 3 4 5

下标i从0开始,当i为2时,初始状态有一组算术级数,123。

                        当i为3时,算数级数有:1234,234

当i为4时,算数级数有:12345,2345,345

通过上面规律不难发现,每次新增加一个元素,都是先在已有元素的基础上append上去,再加上自己新带来的长度为3的一组级数。

所以,dp[i] = dp[i-1] + 1,可以通过前期计算过的子问题来解决新问题,这不就是动态规划吗?

代码如下:

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        if(A.size() < 3)
            return 0;
        
        const int n = A.size();
        int count = 0;
        
        vector<int> dp(n, 0);
        for(int i=2; i<n; ++i){
            if(A[i] - A[i-1] == A[i-1] - A[i-2])
                dp[i] += dp[i-1] + 1;
            count += dp[i];
        }
        return count;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值