1. 程式人生 > >LC 413. Arithmetic Slices

LC 413. Arithmetic Slices

1.題目描述

 

413. Arithmetic Slices

Medium

47095

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,2,3,4,5

有1,2,3,4,5,; 1,2,3,4,; 2,3,4,5; 1,2,3; 2,3,4; 3,4,5 共6個等差數列。雖然1,3,5也是等差數列但它不滿足數字之間連續的條件所以它不算入。

 

2.解題思路

動態規劃問題。用一個二維的int dp[ 2 ][ num ] 陣列記錄中間狀態。num是給的數字的個數。

dp[ 0 ][ i ] 第一行用來記錄到第i個數有多少個等差數列

dp[ 1 ][ i ]第二行用來記錄當前“等差數列”裡有多少個連續的數(這裡之所以打引號是因為有時候兩個數不構成等差數列,此時dp[ 1 ][ i ]的值為2 )

因為題目要求的連續性,可以得到以下等式:

若第i個數和前面不構成等差數列(打斷了當前等差數列):

dp [ 0 ][ i ]  = dp[ 0 ][ i-1 ]   ;等差數列數量沒有變

dp [ 1 ][ i ] = 2  當前不構成等差數列,連續數字的個數為2

同時要更新公差為 第i個數 - 第i-1個數

若第i個數和前面構成等差數列:

dp[ 0 ][ i ] = dp[ 0 ][ i-1 ] + dp[ 1 ][ i-1 ] - 1;
dp[ 1 ][ i ] = dp[ 1 ][ i-1 ] + 1;

不用更新等差數列公差

最後返回dp[ 0 ][ num ] 即可

 

3.實現程式碼

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        int num = A.size();
        if (A.size()<3) return 0;
        int dp[2][num];//第一行用來記錄到A[i]有幾個等差數列,第二行用來記錄目前等差數列有幾個連續的等差數
        memset(dp, 0, sizeof(dp));
        int d = A[1]-A[0];//公差
        dp[0][0] = dp[0][1] = 0;
        dp[1][0] = 1;
        dp[1][1] = 2;
        for (int i=2; i<num; i++) {
            if (A[i]-A[i-1] == d)//前面是一個等差數列,加入的數還構成等差數列的情況
            {
                dp[0][i] = dp[0][i-1] + dp[1][i-1] - 1;
                dp[1][i] = dp[1][i-1] + 1;
            }
            else //與前面的數不構成等差數列
            {
                dp[0][i] = dp[0][i-1];//到這個數為止的等差數列個數不變
                dp[1][i] = 2;//沒有構成等差數列,所以“等差數列”裡連續的數為2個
                d = A[i] - A[i-1];//更新公差d
            }
        }
        return dp[0][num-1];
    }
};