[LeetCode] 873. Length of Longest Fibonacci Subsequence
Problem
https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/description/
Leetcode - Length of Longest Fibonacci Subsequence
Type - Dynamic programming
Difficulty - Medium
Approach & Solution
Let DP[prev][curr]
is the length of Fibonacci-like subsequence which ends with index prev
and curr
of array.
With two-pointer approach, we can find the pair <i, j> such that arr[i] + arr[j] = arr[k] {for (0 <= i < j < k < n)}
.
If the pair matches, dp[j][k] = dp[i][j]+1.
It means append arr[k]
to the subsequence.
data structures & variables:
dp[prev][curr]
: length of Fibonacci-like subsequence which has postfix witharr[prev]
,arr[curr]
.ans
: longest length\
With iterating curr from 2 to n-1:
Initialize start = 0, end = curr -1.
If
arr[start] + arr[end] > arr[curr]
, decrement end by 1 since sum is larger.Else if
arr[start] + arr[end] < arr[curr]
, increment start by 1 since sum is smaller.Else(
arr[start] + arr[end] == arr[curr]
), updatedp[curr][end] = dp[start][end] + 1
Update
ans
to largest.Reduce boundary for both side(
start++
,end—
)
If ans
= 0, return 0 since there’s no such subsequences.
Else, in dp
matrix, we didn’t considered prefix two numbers.
So return ans+2
.
Complexity
Time Complexity: O(n²) - Traverse array with two pointer for n times
Space Complexity: O(n²) - DP Matrix.
Code (C++ | Go)
class Solution {
public:
int lenLongestFibSubseq(vector<int>& arr) {
int n = arr.size();
// dp[prev][curr] = length of fivo seq;
vector<vector<int>> dp(n, vector<int>(n, 0));
int ans = 0;
for(int curr = 2; curr < n; curr++) {
int start = 0;
int end = curr-1;
while(start < end) {
int sum = arr[start] + arr[end];
if(sum > arr[curr]) {
end--;
} else if(sum < arr[curr]) {
start++;
} else {
dp[end][curr] = dp[start][end]+1;
ans = max(ans, dp[end][curr]);
end--;
start++;
}
}
}
ans += 2;
return ans < 3? 0 : ans;
}
};
func lenLongestFibSubseq(arr []int) int {
n := len(arr)
ans := 0
dp := make([][]int, n)
for i := 0; i < n; i++ {
dp[i] = make([]int, n)
for j := 0; j < n; j++ {
dp[i][j] = 0
}
}
for curr := 2; curr < n; curr++ {
start := 0
end := curr-1
for start < end {
sum := arr[start] + arr[end]
if sum > arr[curr] {
end--
} else if sum < arr[curr] {
start++
} else {
dp[end][curr] = dp[start][end] + 1
ans = max(ans, dp[end][curr])
end--
start++
}
}
}
if ans == 0 {
return 0
}
return ans+2
}