[抄题]:
往上走台阶
最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的。
给出 [5,4,1,2,3]
,LIS 是 [1,2,3]
,返回 3
给出 [4,2,4,5,3,7]
,LIS 是 [2,4,5,7]
,返回 4
[思维问题]:
- 不知道怎么处理递增:还是坐标型(有小人在里面跳),用i j来进行比较
- intialization answer都不止一个点:可以从所有的点开始或结束
[一句话思路]:
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
- 是比较nums[i,j]的大小,不是比较lis[i,j]的大小
[二刷]:
[三刷]:
[四刷]:
[五刷]:
[五分钟肉眼debug的结果]:
[总结]:
debug多看数组名
[复杂度]:Time complexity: O(n^2) Space complexity: O(n^2)
[英文数据结构或算法,为什么不用别的数据结构或算法]:
- subarray连续,subsequence不连续
- 二分法也是能不用就不用
- 求具体方案用搜索
[其他解法]:
暴力解法:所有的一起比较
[Follow Up]:
几个“最值”经典算法
LCA:lowest common ancestor(不考)
LIS: longest increasing subsequence
LCS: longest common subsequence
[LC给出的题目变变变]:
673. Number of Longest Increasing Subsequence 计数不能用hashmap,要新建数组
334. Increasing Triplet Subsequence :可行+序列 ,最大、最小两个方向
354. Russian Doll Envelopes:个数、序列、最值
[代码风格] :
public class Solution {
/*
* @param nums: An integer array
* @return: The length of LIS (longest increasing subsequence)
*/
public int lengthOfLIS(int[] nums) {
//corner case
if (nums == null || nums.length == 0) {
return 0;
}
//state
int n = nums.length;
int[] lis = new int[n];
//intialization
for (int i = 0; i < n; i++) {
lis[i] = 1;
}
//function
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {//5-no
lis[i] = Math.max(lis[i], lis[j] + 1);
}
}
}
//answer
int max = lis[0];
for (int i = 1; i < n; i++) {
max = Math.max(max, lis[i]);
}
return max;
}
}