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]
參考了https://discuss.leetcode.com/topic/67413/detailed-explanation-for-java-o-n-2-solution
這道題DP思路還是能想出來,Time O(N^2), Space O(N^2)
T(i, d)
, which denotes the total number of arithmetic subsequence slices ending at index i
with difference d
. The base case and recurrence relation are as follows:
- Base case:
T(0, d) = 0
(This is true for anyd
). - Recurrence relation:
T(i, d) = summation of (1 + T(j, d))
as long as0 <= j < i && d == A[i] - A[j]
.
這個地方有個Corner case, [2,2,3,4,5], 到3的時候,前面有兩個2,這個+1具體應該怎麼處理,如果直接+1並且用T(i,d)表示total number of arithmetic subsequence slices ending at index i
with difference d的話, 那麼到3這個數的時候T(2,1)==2,那不豈是表示3這裡有兩個valid arithmetic subsequence? 而我們知道其實是0個。
所以我們稍作改變T(i,d)表示total number of “generalized” arithmetic subsequence slices ending at index i
with difference d, 這個"generalized" slices允許長度為2,
比如上例[2,2,3,4,5], 考慮diff==1的情況,到3的時候generalized slices number是2, 分別是[2, 3], [2, 3]
到4的時候generalized slices number是3,分別是[2,3,4], [2,3,4], [3,4]
到5的時候generalized slices number是4, 分別是[2,3,4,5], [2,3,4,5], [3,4,5], [4,5]
如此錯了一位,算result的時候也錯一位算
這道題又是一道用HashMap來做DP的題,是因為diff大小不確定,沒有range,像這種沒有range的DP,用HashMap吧
另外語法注意第3行,等號後面map不能再有泛型;第9行等號後面一定要有long
1 public int numberOfArithmeticSlices(int[] A) { 2 int res = 0; 3 Map<Integer, Integer>[] map = new Map[A.length]; 4 5 for (int i = 0; i < A.length; i++) { 6 map[i] = new HashMap<>(i); 7 8 for (int j = 0; j < i; j++) { 9 long diff = (long)A[i] - A[j]; 10 if (diff <= Integer.MIN_VALUE || diff > Integer.MAX_VALUE) continue; 11 12 int d = (int)diff; 13 int c1 = map[i].getOrDefault(d, 0); //orignial value of T(i, d) 14 int c2 = map[j].getOrDefault(d, 0); //the counts from T(j, d) 15 res += c2; 16 map[i].put(d, c1 + c2 + 1); 17 } 18 } 19 20 return res; 21 }