【Leetcode】413. Arithmetic Slices

Description

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.

Discuss

本题是一道动态规划题,可以从最常见的动态规划方法入手。原问题的求解可以转换到子问题的求解。以例子为例[1, 2, 3, 4],数组长度为4,最小长度为3(题目规定),假设[1, 2, 3]已经是满足题目要求的子序列,这时添加4进来,我们只需要判断新添加进来的4和子序列最后一位 3 的差值和子序列的间距差是否相等。如果相等,则满足要求,计数。时间复杂度较高,运行较慢。

看了网上别人的解法,使用的滑动窗口的思想。很简洁,很快。大神还是厉害啊,还需要努力学习啊!

Code 1

class Solution {
    private static final int MAX = Integer.MAX_VALUE;
    public int numberOfArithmeticSlices(int[] A) {
        if (A == null || A.length < 3) { return 0; }
        int n = A.length;
        int[][] dp = new int[n][n];
        //初始化数组
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i - j < 2) { dp[j][i] = MAX; }
            }
        }

        int count = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= i - 2; j++) {
                if (i - j == 2) {
                    dp[j][i] = checkSlices(A, j, i);
                    if (dp[j][i] != MAX) { count++; }
                    continue;
                }
                dp[j][i] = (dp[j][i - 1] != MAX && A[i] - A[i - 1] == dp[j][i - 1]) ? dp[j][i - 1] : MAX;
                if (dp[j][i] != MAX) { count++; }
            }
        }
        return count;
    }

    public int checkSlices(int[] a, int left, int right) {
        int gap = a[left + 1] - a[left];
        int bb = a[right] - a[left + 1];
        if (gap == bb) {
            return bb;
        }
        return MAX;
    }
}

Code 2

class Solution {
    public int numberOfArithmeticSlices(int[] A) {
        if (A == null || A.length < 3) { return 0; }
        int res = 0;
        for (int i = 0; i < A.length; i++) {
            res = res + helper(A, i);
        }
        return res;
    }
    
    private int helper(int[] a, int start) {
        int index = start;
        int count = 0;
        
        while (index < a.length - 2 && a[index + 2] - a[index + 1] == a[index + 1] - a[index]) {
            index++;
            count++;
        }
        return count;
    }
}

posted @ 2018-07-31 11:34  DCREN  阅读(171)  评论(0编辑  收藏  举报