446. Arithmetic Slices II - Subsequence

来源:互联网 发布:js url动态传参数 编辑:程序博客网 时间:2024/05/17 23:00

原题网址:https://leetcode.com/problems/arithmetic-slices-ii-subsequence/

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.


Example:

Input: [2, 4, 6, 8, 10]Output: 7Explanation:All arithmetic subsequence slices are:[2,4,6][4,6,8][6,8,10][2,4,6,8][4,6,8,10][2,4,6,8,10][2,6,10]

思路:动态规划,使用哈希映射保存差值的计数器。

方法一:分别保存两个数的差值计数器和三个以上的差值计数器,此方法会超时。

public class Solution {    public int numberOfArithmeticSlices(int[] A) {        Map<Long, Integer>[] pairCounts = new Map[A.length];        for(int i = 0; i < A.length; i++) pairCounts[i] = new HashMap<>();        Map<Long, Integer>[] seqCounts = new Map[A.length];        for(int i = 0; i < A.length; i++) seqCounts[i] = new HashMap<>();        int numbers = 0;        for(int i = 0; i < A.length - 2; i++) {            for(int j = i + 1; j < A.length - 1; j++) {                long diff = (long)A[j] - A[i];                Integer count = pairCounts[j].getOrDefault(diff, 0);                pairCounts[j].put(diff, ++count);            }        }        for(int i = 1; i < A.length - 1; i++) {            for(int j = i + 1; j < A.length; j++) {                long diff = (long)A[j] - A[i];                Integer pCountI = pairCounts[i].getOrDefault(diff, 0);                Integer sCountI = seqCounts[i].getOrDefault(diff, 0);                Integer sCountJ = seqCounts[j].getOrDefault(diff, 0);                if (pCountI + sCountI + sCountJ > 0) {                    seqCounts[j].put(diff, pCountI + sCountI + sCountJ);                    numbers += pCountI + sCountI;                }            }        }        return numbers;    }}

方法二:参考https://discuss.leetcode.com/topic/67413/detailed-explanation-for-java-o-n-2-solution,精妙之处在于解决了一对数字和三个以上数字的差值计数器问题。

public class Solution {    public int numberOfArithmeticSlices(int[] A) {        int result = 0;        Map<Integer, Integer>[] counts = new Map[A.length];        for(int i = 0; i < A.length; i++) {            counts[i] = new HashMap<>();            for(int j = 0; j < i; j++) {                long diff = (long)A[i] - A[j];                if (diff <= Integer.MIN_VALUE || diff > Integer.MAX_VALUE) continue;                int ci = counts[i].getOrDefault((int)diff, 0);                int cj = counts[j].getOrDefault((int)diff, 0);                counts[i].put((int)diff, ci + cj + 1);                result += cj;            }        }        return result;    }}

C++代码:

class Solution {public:    int numberOfArithmeticSlices(vector<int>& A) {        int res = 0;        vector<unordered_map<int, int>> counts(A.size());        for(int i = 1; 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;// do not ignore this step, it will help you save time & space to pass OJ.                int diff = A[i] - A[j];                int ci = counts[i].find(diff) == counts[i].end() ? 0 : counts[i][diff];                int cj = counts[j].find(diff) == counts[j].end() ? 0 : counts[j][diff];                counts[i][diff] = ci + cj + 1;                res += cj;            }        }        return res;    }};

Python代码:

class Solution(object):    def numberOfArithmeticSlices(self, A):        """        :type A: List[int]        :rtype: int        """        res = 0        counts = {}        for i in range(len(A)):            counts[i] = {}            for j in range(i):                diff = A[i] - A[j]                ci = counts[i][diff] if diff in counts[i] else 0                cj = counts[j][diff] if diff in counts[j] else 0                res += cj                counts[i][diff] = ci + cj + 1        return res        

JavaScript代码:

/** * @param {number[]} A * @return {number} */var numberOfArithmeticSlices = function(A) {    var res = 0;    var counts = [];    for(i = 0; i < A.length; i++) {        var countI = {};        counts.push(countI);        for(j = 0; j < i; j++) {            if (A[i] - A[j] <=  Number.MIN_SAFE_INTEGER || A[i] - A[j] >=  Number.MAX_SAFE_INTEGER) continue;            var diff = (A[i] - A[j]).toString();            var ci = counts[i][diff] || 0;            var cj = counts[j][diff] || 0;            // console.log("i="+toString(i)+",j="+toString(j)+",diff="+diff+",ci="+toString(ci)+",cj="+toString(cj));            counts[i][diff] = ci + cj + 1;            res += cj;        }    }    return res;};

但我的JavaScript无法通过测试。





0 0
原创粉丝点击