76. Longest Increasing Subsequence
Tag:
Dynamic Problem
Main Idea:
Classic DP Problem. Let d p [ i ] \ dp[i] dp[i] represents the number of longest increasing subsequence at the position i. For initialization, each element is assign as 1. As for update equation, it would be: for 0 < j < i < n, d p [ i ] = m a x ( d p [ i ] , d p [ j ] + 1 ) . \ dp[i] = max(dp[i], dp[j]+1). dp[i]=max(dp[i],dp[j]+1).
Tips/Notes:
- Don’t forget to initialize the dp[i].
Time/Space Cost:
Time Cost:
O
(
n
2
)
\ O(n^2)
O(n2)
Space Cost:
O
(
n
)
\ O(n)
O(n)
Code:
class Solution {
public:
/**
* @param nums: An integer array
* @return: The length of LIS (longest increasing subsequence)
*/
int longestIncreasingSubsequence(vector<int> &nums) {
// write your code here
int len = nums.size();
if(len == 0) return 0;
int res = 0;
vector<int> dp(len+1, 0);
for(int i = 0; i < len; i++){
dp[i] = 1;
for(int j = 0; j < i; j++){
if(nums[i] > nums[j]){
dp[i] = max(dp[i], dp[j] + 1);
}
res = max(res, dp[i]);
}
}
return res;
}
};
Followup Problem: 398. Longest Continuous Increasing Subsequence II
Main Idea:
DP-Memorization Problem. In this problem, we need to use d p [ i ] [ j ] \ dp[i][j] dp[i][j] to record each position’s information. Let d p [ i ] [ j ] \ dp[i][j] dp[i][j] be the longest increasing subsequence length ending at row i, column j (i, j). For initialization, default value of d p [ i ] [ j ] \ dp[i][j] dp[i][j] will be -1, when it’s in SEARCH() function, set as 1.
Then, update equation, let (nx, ny) be one of four directions of (i,j), IF d p [ i ] [ j ] > d p [ n x ] [ n y ] \ dp[i][j] > dp[nx][ny] dp[i][j]>dp[nx][ny], d p [ i ] [ j ] = m a x ( d p [ [ i ] [ j ] , d p [ n x ] [ n y ] + 1 ) \ dp[i][j] = max(dp[[i][j], dp[nx][ny]+1) dp[i][j]=max(dp[[i][j],dp[nx][ny]+1).
The answer will be the maximum element in d p [ i ] [ j ] \ dp[i][j] dp[i][j].
Tips/Notes:
- 2D vector definition: vector<vector>(row, vector(col, -1));
- Note the value of d p [ i ] [ j ] \ dp[i][j] dp[i][j]. The transition would be (-1 -> 1 -> maxValue). When d p [ i ] [ j ] = − 1 \ dp[i][j]=-1 dp[i][j]=−1, it means this element haven’t been searched; When d p [ i ] [ j ] = 1 \ dp[i][j]=1 dp[i][j]=1, it means begin to search this element; When d p [ i ] [ j ] = m a x V a l u e \ dp[i][j]=maxValue dp[i][j]=maxValue, it means this element has been searched.
Time/Space Cost:
Time Cost:
O
(
n
m
)
\ O(nm)
O(nm)
Space Cost:
O
(
n
m
)
\ O(nm)
O(nm)
Code:
class Solution {
public:
/**
* @param matrix: A 2D-array of integers
* @return: an integer
*/
vector<vector<int>> dp;
int row, col;
int longestContinuousIncreasingSubsequence2(vector<vector<int>> &matrix) {
// write your code here
row = matrix.size();
col = (row == 0)? 0 : matrix[0].size();
// default as -1, which means haven't searched
dp = vector<vector<int>>(row, vector<int>(col, -1));
int res = 0;
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
// search row i, column j
search(matrix, i, j);
res = max(res, dp[i][j]);
}
}
return res;
}
void search(vector<vector<int>> &matrix, int x, int y){
if(dp[x][y] != -1)
return;
// direction vector
vector<int> d = {0,1,0,-1,0};
// NOTE HERE: must initializa the dp[x][y]
dp[x][y] = 1;
for(int i = 0; i < 5; i++){
int nx = x + d[i];
int ny = y + d[i+1];
if(nx >= 0 && nx < row && ny >= 0 && ny < col){
if(matrix[nx][ny] < matrix[x][y])
{
// MUST search dp[nx][ny] first
search(matrix, nx, ny);
dp[x][y] = max(dp[x][y], dp[nx][ny] + 1);
}
}
}
}
};