Printing Longest Increasing Subsequence
Problem Statement:ā
Print Longest Increasing Subsequence
-
Example:
ā Solution: Tabulation + Reconstructionā
class Solution {
public:
vector<int> getLIS(vector<int>& arr) {
int n = arr.size();
vector<int> dp(n, 1); // dp[i] = LIS ending at i
vector<int> hash(n); // hash[i] = previous index in LIS ending at i
for(int i = 0; i < n; i++){
hash[i] = i; // Initially point to itself
for(int prev = 0; prev < i; prev++){
if(arr[i] > arr[prev] && dp[i] < dp[prev] + 1){
dp[i] = dp[prev] + 1;
hash[i] = prev;
}
}
}
// Find max length and its index
int maxLen = -1, lastIndex = -1;
for(int i = 0; i < n; i++){
if(dp[i] > maxLen){
maxLen = dp[i];
lastIndex = i;
}
}
// Reconstruct LIS using hash
vector<int> lis;
lis.push_back(arr[lastIndex]);
while(hash[lastIndex] != lastIndex){
lastIndex = hash[lastIndex];
lis.push_back(arr[lastIndex]);
}
reverse(lis.begin(), lis.end());
return lis;
}
};
š How It Worksā
dp[i]keeps track of the length of LIS ending at indexi.hash[i]stores the index of the previous element in the LIS ending ati.- After filling
dpandhash, we:- Find the maximum value in
dp. - Use
hashto backtrack from that index to reconstruct the LIS.
- Find the maximum value in
š§© Key Ideaā
- At every index
i, we check allj < iand extend the subsequencedp[i] = max(dp[j] + 1)ifarr[i] > arr[j]. - Track the path using
hashso we can rebuild the actual subsequence.
ā±ļø Time & Space Complexityā
| Operation | Complexity |
|---|---|
| Time Complexity | O(N²) |
| Space Complexity | O(N) |
ā ļø Edge Casesā
- Empty array ā return empty list.
- All elements equal ā return single element.
- Strictly decreasing array ā return any one element.
š” Other Approachesā
| Method | Notes |
|---|---|
| DP + Hash (this one) | ā Reconstructs LIS |
| Binary Search + Parent | ā O(N log N) reconstruction |
| DP only | ā Can't get sequence |
š Related Problemsā
- Longest Increasing Subsequence
- Number of Longest Increasing Subsequence
- Longest Bitonic Subsequence (GFG)
- Russian Doll Envelopes
š¬