Given an integer array arr
and an integer difference
, return the length of the longest subsequence in arr
which is an arithmetic sequence such that the difference between adjacent elements in the subsequence equals difference
.
A subsequence is a sequence that can be derived from arr
by deleting some or no elements without changing the order of the remaining elements.
For example:
arr = [1,2,3,4], difference = 1
. The longest arithmetic subsequence is [1,2,3,4]
. The function should return 4.arr = [1,3,5,7], difference = 1
. The longest arithmetic subsequence is any single element. The function should return 1.arr = [1,5,7,8,5,3,4,2,1], difference = -2
. The longest arithmetic subsequence is [7,5,3,1]
. The function should return 4.Write a function that efficiently finds the length of the longest arithmetic subsequence.
A brute-force solution would involve generating all possible subsequences of the input array arr
and then, for each subsequence, checking if it forms an arithmetic sequence with the given difference
. We then keep track of the longest arithmetic subsequence found so far.
This approach has a time complexity of O(2^n * n), where n is the length of arr
. This is because there are 2^n possible subsequences, and for each subsequence, we might need to iterate through it to check if it's an arithmetic sequence.
We can use dynamic programming to solve this problem more efficiently. We'll use a hash map (or dictionary) to store the length of the longest arithmetic subsequence ending at each number in arr
. Specifically, dp[num]
will store the length of the longest arithmetic subsequence ending with the number num
.
Here's the algorithm:
dp
.arr
.num
in arr
:
num - difference
is in dp
.num - difference
. So the length of the longest arithmetic subsequence ending at num
will be dp[num - difference] + 1
.num
starts a new arithmetic subsequence of length 1.dp[num]
with the appropriate length.Let's trace the example arr = [1, 5, 7, 8, 5, 3, 4, 2, 1]
and difference = -2
.
1
: dp[1] = 1
, max_len = 15
: dp[5] = 1
, max_len = 17
: dp[7] = 1
, max_len = 18
: dp[8] = 1
, max_len = 15
: dp[5] = 1
, max_len = 1 (no change because it's the first time 5
has created a sequence)3
: dp[3] = dp[5] + 1 = 2
, max_len = 24
: dp[4] = 1
, max_len = 22
: dp[2] = dp[4] + 1 = 2
if 4 existed, dp[2] = dp[4] + 1
, max_len = 21
: dp[1] = dp[3] + 1 = 3
, max_len = 3Continuing in this fashion:
arr[5] = 3
: dp[3] = dp[5] + 1 = 2
arr[6] = 4
: dp[4] = 1
arr[7] = 2
: dp[2] = dp[4] + 1 = 2
if dp[4] existed. max_len = 2arr[8] = 1
: dp[1] = dp[3] + 1 = 3
. max_len = 3arr[6] = 5
: dp[5] = 1
arr[7] = 3
: dp[3] = dp[5] + 1 = 2
arr[8] = 1
: dp[1] = dp[3] + 1 = 3
arr[9] = 4
: dp[4] = 1
arr[10] = 2
: dp[2] = dp[4] + 1 = 2
arr[11] = 1
: dp[1] = dp[3] + 1 = 3
arr[6] = 7
: dp[7] = 1
arr[7] = 5
: dp[5] = dp[7] + 1 = 2
arr[8] = 3
: dp[3] = dp[5] + 1 = 3
arr[9] = 1
: dp[1] = dp[3] + 1 = 4
. max_len = 4def longestArithSeq(arr, difference):
dp = {}
max_len = 0
for num in arr:
if num - difference in dp:
dp[num] = dp[num - difference] + 1
else:
dp[num] = 1
max_len = max(max_len, dp[num])
return max_len
arr
, because we iterate through the array once.arr
, because, in the worst case, the dp
hash map might store an entry for each element in arr
.arr
is empty, the longest arithmetic subsequence has length 0. The code handles this case correctly because max_len
is initialized to 0.difference
variable can be large, so the space used by the dp
map could grow depending on the data in arr
.