LeetCode413. Arithmetic Slices c++

题目描述

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.

样例输入

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.

限制条件

最后一组数据数据量为5000,建立Int[5000][5000]出现爆栈

解题思路

  1. 思路一

来自LeetCode大神,先附上代码

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
	    int curr = 0, sum = 0;
	    for (int i=2; i<A.length; i++)
	        if (A[i]-A[i-1] == A[i-1]-A[i-2]) {
	            curr += 1;
	            sum += curr;
	        } else {
	            curr = 0;
	        }
	    return sum; 
    }
};

curr指以当前index结尾的“Arithmetic Slices”的数量

例如
A = [1,2,3,4,5]
i = 2, A[i]=3, curr = 1
i = 3, A[i]=4, curr = 2
只要没有断裂的情况curr可以持续+1
  1. 思路二
例如
A = [1,2,3,4]

2,3,4是算数切分
1,2,3是算数切分
因为1,2,3和2,3,4是算数切分,则1,2,3,4是算数切分

1D DP
dp[i][j]为从坐标i到j是否为算数切分
i = n-3开始遍历,对每个ij=i+2开始遍历
j=i+2时,可直接用A[j]-A[i+1]==A[i+1]-A[i]判断
其他情况,用dp[i-1][j]==1&&dp[i][j-1]==1判断
例如,A=[1,2,3,4], (1,2,3)是算数切分并且(2,3,4)也为算数切分,则(1,2,3,4)为算数切分

优化:

  • 将二维数据降至一维,即只存储前一个i的结果
  • dp[i][j]!=1,[i,j+1]必定不是段数切分,无需遍历后续j,break

代码如下:

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        int n = A.size();
        if(n<3)
            return 0;
        int dp[n][n] = {0};
        int count = 0;
        for(int i = n-3;i>=0;i--)
            for(int j=i+2;j<n;j++){
                if(j==i+2){
                    if(A[i+1]-A[i]==A[i+2]-A[i+1])
                        {
                            dp[i][j]=1;
                            count++;
                        }
                }
               else if(dp[i+1][j]==1&&dp[i][j-1]==1){
                    dp[i][j]=1;
                    count++;
                }else break; //此处跳出
            }

        }
        return count;
        
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值