leetcode 446 等差数列划分 II

数组 A 包含 N 个数,且索引从 0 开始。该数组子序列将划分为整数序列 (P0, P1, ..., Pk),P 与 Q 是整数且满足 0 ≤ P0 < P1 < ... < Pk < N。

 

如果序列 A[P0],A[P1],...,A[Pk-1],A[Pk] 是等差的,那么数组 A 的子序列 (P0,P1,…,PK) 称为等差序列。值得注意的是,这意味着 k ≥ 2。

函数要返回数组 A 中所有等差子序列的个数。

输入包含 N 个整数。每个整数都在 -231 和 231-1 之间,另外 0 ≤ N ≤ 1000。保证输出小于 231-1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence

题目分析:像这样的测试用例,[2,2,3,4,5,5],用遍历的方法需要记录的数:
比如遍历到以三为最后一个元素的数组是否含有等差数列时,虽然此时没有符合条件的等差数列但是应当把这个3之前的元素与3之间的步长(即两元素的差值)都记录下来以备以后使用,
根据需求:需要一个二维数组或者--当然看到二维数组就头疼该给多大的数组,很有可能会不够用,当然,步长(两数的差值)并不会遍历整个整数数轴,所以用hashmap代替即可,python中应该也可使用字典
 
下面是java代码:

class Solution {
    public int numberOfArithmeticSlices(int[] A) {
        HashMap<Integer, Integer>[] diffMaps = new HashMap[A.length];
        int res = 0;
        for(int i = 0;i<A.length;i++){
            HashMap<Integer, Integer> diffMap = new HashMap();
            diffMaps[i] = diffMap;
            long num = A[i];
            for(int j=0;j<i;j++){
                if(num-A[j]>Integer.MAX_VALUE)
                    continue;
                if(num-A[j]<Integer.MIN_VALUE)
                    continue;
                int diff = (int)(num-A[j]);
                int count = diffMaps[j].getOrDefault(diff, 0);
                diffMaps[i].put(diff,diffMaps[i].getOrDefault(diff, 0)+count+1);
                res+=count;
            }
        }
        return res;
    }
}
python代码:

#python3
from collections import defaultdict
class Solution:
    def numberOfArithmeticSlices(self,A):
        dp,ans=[defaultdict(int)],0 #以每个数字作为等差数列最后一项的数组的个数(俩数字也记为1 但是不能加到ans里去)
        for i,cur in enumerate(A[1:],1):
            cur_dict=defaultdict(int)
            for j,prev in enumerate(A[:i]):
                diff=cur-prev
                tmp=dp[j][diff]
                ans+=tmp
                cur_dict[diff]+=tmp+1 #如上面所说的 俩数字记为1(本质上算不上是等差数列 因为等差数列至少要三项)
            dp.append(cur_dict)
        return ans


原文地址:https://www.cnblogs.com/hongdoudou/p/13071522.html