Skip to content

Commit ef7919d

Browse files
committed
Implement longest-arithmetic-subsequence-of-given-difference
name: longest-arithmetic-subsequence-of-given-difference url: https://leetcode.com/problems/longest-arithmetic-subsequence-of-given-difference difficulty: 2 time: 128 ms time-rank: 98.59 % time-complexity: O(N) space: 56.6 MB space-rank: 62.32 % space-complexity: O(N) Fixes #316 Signed-off-by: Christopher Friedt <[email protected]>
1 parent 9a0b3a6 commit ef7919d

2 files changed

+20
-50
lines changed

longest-arithmetic-subsequence-of-given-difference-test.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ TEST(LongestArithmeticSubsequenceOfGivenDifference, 3_4_n3_n2_n4__n5) {
3434
EXPECT_EQ(2, Solution().longestSubsequence(arr, difference));
3535
}
3636

37-
#if 0
3837
TEST(LongestArithmeticSubsequenceOfGivenDifference, huge__5692) {
3938
auto arr = vector<int>{
4039
1806, -6771, -1534, -5016, 6991, 149, -615, 1787, -1311,
@@ -11149,7 +11148,6 @@ TEST(LongestArithmeticSubsequenceOfGivenDifference, huge__5692) {
1114911148
-2820, -6121, 9378, 6091, 7589, -9460, -1655, -9614, 7073,
1115011149
6444, -5651, -4411, -4891, -6234, 8829, -3465, 2642, 7110,
1115111150
-1391};
11152-
int difference = 15;
11153-
EXPECT_EQ(1, Solution().longestSubsequence(arr, difference));
11151+
int difference = 5692;
11152+
EXPECT_EQ(4, Solution().longestSubsequence(arr, difference));
1115411153
}
11155-
#endif

longest-arithmetic-subsequence-of-given-difference.cpp

+18-46
Original file line numberDiff line numberDiff line change
@@ -10,66 +10,38 @@
1010
// difficulty: 2
1111
// clang-format on
1212

13-
#include <climits>
13+
#include <unordered_map>
14+
#include <unordered_set>
1415
#include <vector>
1516

1617
using namespace std;
1718

18-
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
19-
os << "[";
20-
for (size_t i = 0, N = v.size(); i < N; ++i) {
21-
os << v[i];
22-
if (i < N - 1) {
23-
os << ", ";
24-
}
25-
}
26-
os << "]";
27-
return os;
28-
}
29-
3019
class Solution {
3120
public:
3221
int longestSubsequence(vector<int> &arr, int difference) {
3322
/*
34-
Let's say that arr is length 1, e.g. A = [1], and difference is -42.
35-
36-
Would the longest subsequence be 1 as a base case? What if A had length
37-
0? Would the longest subsequence be 0 as a base case?
23+
If we proceed from the 0th element in arr to the end
24+
we can check if arr[i] - difference already exists in O(1) time
25+
by using an unordered_map<int,int>, where the key is the
26+
value from arr[j], 0 <= j < i, and the value is the length
27+
of the subsequence finishing with arr[j].
3828
39-
Say A = [1,2,3,4] and difference == 1
29+
If the key exists, then simply add a one to it for a new entry, arr[i].
30+
if the key does not exist, then simply set it to one (the same as adding one
31+
to a value not already in the map with the [] operator).
4032
41-
i j A[i] A[j] d LS(i) LS(j)
42-
---------------------------------
43-
0 - 1 - - 1 -
44-
1 0 2 1 1 2 1
45-
2 0 3 1 2 1 1
46-
2 1 3 2 1 3 2
47-
3 0 4 1 3 1 1
48-
3 1 4 2 2 1 2
49-
3 2 4 3 1 4 3
33+
Keep track of the maximum subsequence length with a separate variable.
5034
51-
LS(i) = 1 + max(LS(j)), 0 < j < i and d = A[i] - A[j] == difference
52-
= 1 if no such j exists
53-
54-
There is a problem though, in that we still need to remember the max
55-
of LS(.), because the max will not necessarily be at the last position.
56-
To solve that, maintain a max_len variable initialized to INT_MIN.
35+
O(N)
5736
*/
58-
int N = arr.size();
59-
vector<int> dp(N, 1);
60-
int max_len = INT_MIN;
6137

62-
for (int i = 1; i < N; ++i) {
63-
for (int j = 0; j < i; ++j) {
64-
if (arr[i] - arr[j] == difference) {
65-
dp[i] = max(dp[i], 1 + dp[j]);
66-
}
67-
}
68-
max_len = max(max_len, dp[i]);
69-
}
38+
int max_len = 0;
39+
unordered_map<int, int> dp;
7040

71-
// cout << "arr: " << arr << ", difference: " << difference << endl;
72-
// cout << "dp: " << dp << endl;
41+
for (auto &a : arr) {
42+
dp[a] = dp[a - difference] + 1;
43+
max_len = max(max_len, dp[a]);
44+
}
7345

7446
return max_len;
7547
}

0 commit comments

Comments
 (0)