LeetCode446. 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, 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 subsequence slice of that array is any sequence of integers (P0, P1, ..., Pk) such that 0 ≤ P0 < P1 < ... < Pk < N.
A 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: 7 Explanation:
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]
分析
又是一个光题目就得看半天的算法题,前面可以直接无视,直接看它给出的例子就知道这题到底要求什么了。看了下解答,方法是利用dp。
最少需要记住两个参数,序列的第一个或者最后一个元素,以及这个序列中的公共差。
f[i][d] denotes the number of arithmetic subsequences that ends with A[i] and its common difference is d.
下一步是寻找状态转移表达式已建立子问题之间的桥梁。试想如果我们现在想要把一个新元素A[i]插入到一个现有的arithmetic sequence中来形成一个新的arithmetic sequence,那么只有在A[i]和原来的sequence中最后一个元素的差等于其公共差的情况下才能形成新的arithmetic sequence。

这里比较难理解的便是 T(i, d) = summation of (1 + T(j, d)) as long as 0 <= j < i && d == A[i] - A[j]. 这个式子,还是用个例子来说明比较好,如果当前的 j 是 3,公差是1的话 :
1,2,3,4
2,3,4
两个可能。3,4因为元素个数少于3个所以不构成arithmetic sequence,现在我们将A[i]=A[5]=5加入以构成新的arithmetic sequence,
1,2,3,4,5
2,3,4,5
3,4,5
多了一个,并不是完全等于之前的T(j, d)。

dp的特性,子问题之间有重复,和分治不同。
代码
public int numberOfArithmeticSlices(int[] A) {
int res = 0;
Map<Integer, Integer>[] map = new Map[A.length];
for (int i = 0; i < A.length; i++) {
map[i] = new HashMap<>(i);
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 d = (int)diff;
int c1 = map[i].getOrDefault(d, 0);
int c2 = map[j].getOrDefault(d, 0);
res += c2;
map[i].put(d, c1 + c2 + 1);
}
}
return res;
}
map数组用来存储中间计算结果T(i, d),数组的index对应i,表示arithmetic sequence以A[i]结束;key是公共距离差d,value是arithmetic sequence的个数,也就是T(i, d)。也就说用了map数组一下子存储了三个基本信息,厉害了。

这题真的好难。
LeetCode446. Arithmetic Slices II - Subsequence的更多相关文章
- Arithmetic Slices II - Subsequence LT446
446. Arithmetic Slices II - Subsequence Hard A sequence of numbers is called arithmetic if it consis ...
- [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- LeetCode 446. Arithmetic Slices II - Subsequence
原题链接在这里:https://leetcode.com/problems/arithmetic-slices-ii-subsequence/ 题目: A sequence of numbers is ...
- [Swift]LeetCode446. 等差数列划分 II - 子序列 | Arithmetic Slices II - Subsequence
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- Leetcode: Arithmetic Slices II - Subsequence
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- 446. Arithmetic Slices II - Subsequence
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- 446 Arithmetic Slices II - Subsequence 算数切片之二 - 子序列
详见:https://leetcode.com/problems/arithmetic-slices-ii-subsequence/description/ C++: class Solution { ...
- 第六周 Leetcode 446. Arithmetic Slices II - Subsequence (HARD)
Leetcode443 题意:给一个长度1000内的整数数列,求有多少个等差的子数列. 如 [2,4,6,8,10]有7个等差子数列. 想了一个O(n^2logn)的DP算法 DP[i][j]为 对于 ...
- [LeetCode] Arithmetic Slices 算数切片
A sequence of number is called arithmetic if it consists of at least three elements and if the diffe ...
随机推荐
- 团体程序设计天梯赛 L2-028. 秀恩爱分得快
1.输入-0(第一部分.第二部分),输出-02.只统计与两个人的亲密程度,否则超时 Data: 4 14 -0 1 -2 3-0 1 -0 1 ------ 4 1 3 1 -2 3-0 1 -0 1 ...
- css基础--常用css属性02
上篇地址:css基础--常用css属性01 本文参考菜鸟教程和w3school 1 浮动和清除浮动 在上篇的第十一节--定位中说道: CSS 有三种基本的定位机制:普通流.浮动和绝对定位. 普通流和 ...
- ElasticStack系列之七 & IK自动热更新原理与实现
一.热更新原理 elasticsearch开启加载外部词典功功能后,会每60s间隔进行刷新字典.具体原理代码如下所示: public void loadDic(HttpServletRequest r ...
- Hadoop生态圈-Hbase的rowKey设计原则
Hadoop生态圈-Hbase的rowKey设计原则 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Java 多线程实现
第一种方式 package demo3; public class Threddemo { public static void main(String[] args) { MyThred mt = ...
- 美轮美奂!9款设计独特的jQuery/CSS3全新应用插件(下拉菜单、动画、图表、导航等)
今天要为大家分享9款设计非常独特的jQuery/CSS3全新应用插件,插件包含菜单.jQuery焦点图.jQuery表单.jQuery图片特效等.下面大家一起来看看吧. 1.jQuery水晶样式下拉导 ...
- kdissert:linux下的自由脑图软件
----------------------------------------------------作者: 吉庆 email: jiqingwu@gmail.commainpage: http ...
- Bzoj4763 雪辉
Time Limit: 39 Sec Memory Limit: 666 MBSubmit: 151 Solved: 80 Description 上次立下的NOIP退役Flag没有成功 这次 ...
- Sql Server 逻辑文件 '' 不是数据库 '' 的一部分。请使用 RESTORE FILELISTONLY 来列出逻辑文件名。
当使用语句还原数据库时,报如下错误: 消息 3234,级别 16,状态 2,第 29 行逻辑文件 'LenborMealOrder_Base_2017' 不是数据库 'Members_01' 的一部分 ...
- 文件操作fstream
c++文件操作详解 2009-04-16 20:46:35| 分类: C/C++|举报|字号 订阅 C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ost ...