[Leetcode] 446. Arithmetic Slices II

来源:互联网 发布:网站编程语言有哪些 编辑:程序博客网 时间:2024/05/29 09:43

题目

A sequence of numbers 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 sequences:

1, 3, 5, 7, 97, 7, 7, 73, -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 subsequence slice of that array is any sequence of integers (P0, P1, ..., Pk) such that 0 ≤ P0 < P1 < ... < Pk < N.

subsequence slice (P0, P1, ..., Pk) of array A is called arithmetic if the sequence A[P0], A[P1], ..., A[Pk-1], A[Pk] is arithmetic. In particular, this means that k ≥ 2.

The function should return the number of arithmetic subsequence slices in the array A.

The input contains N integers. Every integer is in the range of -231 and 231-1 and 0 ≤ N ≤ 1000. The output is guaranteed to be less than 231-1.

思路

1、回溯法:我开始自然而然地想到了回溯法,也就是每个元素我们试着将它加入等差数列中,看看是否符合要求,然后再将它取出来。最终统计出符合条件的等差数列的个数。然而却无法通过大数据测试,因为对于[1,1,1,1,1,1,1,1,1,1,1,1]这样的测试用例,回溯法会涉及到大量的重复计算。

2、动态规划:定义dp[index][diff]表示以A[index]结尾,等差值为diff的序列的个数,那么状态转移方程为dp[index][diff] = sum(dp[i][diff] + 1),其中0 <= i <= index - 1。注意sum内部+1是由于包含了A[index]本身。在实现中,由于以A[index]结尾的序列的diff个数可能是稀疏的, 所以我们采用vector<unordered_map<int,int>> 这种数据结构来表示dp。这种算法的时间复杂度是O(n^2),可以顺利通过大数据测试。

代码

1、回溯法:

class Solution {public:    int numberOfArithmeticSlices(vector<int>& A) {        vector<int> line;        int count = 0;        DFS(A, 0, line, count);        return count;    }private:    void DFS(vector<int> &A, int index, vector<int> &line, int &count) {        if (index == A.size()) {            if (line.size() >= 3) {                ++count;            }            return;        }        // include A[index]        if (line.size() < 2) {            // include A[index]            line.push_back(A[index]);            DFS(A, index + 1, line, count);            line.pop_back();        }        else {                      // line.size() >= 2            // A[index] can be included            int size = line.size();            long long diff1 = static_cast<long long>(A[index]) - line[size - 1];            long long diff2 = static_cast<long long>(line[size - 1]) - line[size - 2];            if (diff1 == diff2) {                line.push_back(A[index]);                DFS(A, index + 1, line, count);                line.pop_back();            }                    }        // do not include A[index]        DFS(A, index + 1, line, count);    }};

2、动态规划:

class Solution {public:    int numberOfArithmeticSlices(vector<int>& A) {        if(A.empty()) {            return 0;        }        vector<unordered_map<int,int>> dp(A.size());    //[index, [difference, count]]        int res = 0;        for(int i = 0; i < A.size(); ++i) {            for(int j = 0; j < i; ++j) {                if((long)A[i] - (long)A[j] > INT_MAX || (long)A[i] - (long)A[j] < INT_MIN) {                    continue;                }                int dif = A[i] - A[j];                dp[i][dif] += 1;                if(dp[j].find(dif) != dp[j].end()) {                    dp[i][dif] += dp[j][dif];                    res += dp[j][dif];                }            }        }        return res;    }};
原创粉丝点击