413. Arithmetic Slices

来源:互联网 发布:指尖陀螺 知乎 编辑:程序博客网 时间:2024/06/06 18:32

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的连续等差数列

下面是我最初的思路,
首先易知给定一个长度为n的等差数列T = [1, 2, 3, 4,……n],1开头的长度不小于3的连续等差数列个数为n-2,2开头的个数为n-1……,n-2开头的个数为1,其余为0,故总共的个数为1+2+……+n-2=(n-2)*(n-1)/2。

故依次找出数组中每个最长的连续等差数列并加上其中满足题意的个数。
时间复杂度O(n),空间复杂度O(1)

public class Solution {    public int numberOfArithmeticSlices(int[] A) {        if(A == null || A.length < 3)   return 0;        int sum = 0, i = 0, j;        while(i < A.length - 2){            j = i + 1;            while(j < A.length && A[j] - A[j - 1] == A[i+1] - A[i])   j++;            //该最长的连续等差数列总长度为j-i            sum += (j-i-2)*(j-i-1)/2;            i = j - 1;        }        return sum;    }}

另外,可以用动态规划来做。
dp[i]代表以A[i]结尾的符合题意的等差数列个数
当A[i]-A[i-1] == A[i-1]-A[i-2]时,dp[i]包括以A[i-1]结尾的符合题意的等差数列和等差数列A[i-2], A[i-1], A[i],即dp[i] = dp[i-1]+1。否则,dp[i]等于0。
时间复杂度O(n),空间复杂度O(n)

public class Solution {    public int numberOfArithmeticSlices(int[] A) {        if(A == null || A.length < 3) return 0;        int result = 0;        int dp[] = new int[A.length];        if(A[1] - A[0] == A[2] - A[1]) dp[2] = 1;        result = dp[2];        for(int i = 3; i < A.length; ++i) {            if(A[i-1] - A[i-2] == A[i] - A[i-1])    dp[i] = dp[i-1] + 1;            result += dp[i];        }        return result;    }}

由于dp[i]只与dp[i-1]有关,所以可以进行优化,使用一个变量cur记录dp[i-1],则每次若A[i-1] - A[i-2] == A[i] - A[i-1],cur+1,否则cur=0。
时间复杂度O(n),空间复杂度O(1),与我最初的方法是类似的

public class Solution {    public int numberOfArithmeticSlices(int[] A) {        if(A == null || A.length < 3) return 0;        int cur = 0, sum = 0;        for(int i = 2; i < A.length; i++){            if(A[i] - A[i-1] == A[i-1] - A[i-2]){                cur += 1;                sum += cur;            }else{                cur = 0;            }        }        return sum;    }}
原创粉丝点击