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.
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: 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无法通过测试。
- 446. Arithmetic Slices II - Subsequence
- 446. Arithmetic Slices II - Subsequence
- 446. Arithmetic Slices II - Subsequence***
- 446. Arithmetic Slices II - Subsequence
- Arithmetic Slices II - Subsequence
- LeetCode 446. Arithmetic Slices II - Subsequence
- LeetCode 446. Arithmetic Slices II - Subsequence
- Leetcode-446. Arithmetic Slices II - Subsequence
- 446. Arithmetic Slices II
- 446. Arithmetic Slices II
- 446. Arithmetic Slices II
- 446. Arithmetic Slices II
- 446. Arithmetic Slices II
- [LeetCode]446. Arithmetic Slices II
- LeetCode 446. Arithmetic Slices II
- [Leetcode] 446. Arithmetic Slices II
- leetcode 446. Arithmetic Slices II
- Arithmetic Slices II
- Linux最基本的一些命令
- Android 解决ListView、GridView在首次显示时adapter可能多次调用getView的问题
- 赫夫曼编码长度计算问题?
- [Leetcode] Container With Most Water Python
- 模拟题:流量问题
- 446. Arithmetic Slices II - Subsequence
- 树结构练习——判断给定森林中有多少棵树-并查集
- java多线程-03-阻塞队列简介
- 【安价】亚拉奈夫想要复兴贫弱男爵家的样子【内政】2
- 如何获取linux下命令源码
- sssss
- 我的英语也不是很好,还不是照样学java编程,还不是照样写代码啊,献给每一个努力的小伙伴们!(雪豹软件工作室)
- 《重构---改善既有代码的设计》总结二之代码的坏味道
- Java设计模式——六大设计原则