最长递增子序列

客官°小女子只卖身不卖艺 2024-03-25 23:05 177阅读 0赞

300.力扣

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

dp:

  1. // int [] dp = new int[nums.length];
  2. // Arrays.fill(dp,1);
  3. // for(int i = 0; i < nums.length; i++){
  4. // for(int j = i; j < nums.length; j++){
  5. // if(nums[i] < nums[j]){
  6. // dp[j] = Math.max(dp[j], dp[i] + 1);
  7. // }
  8. // }
  9. // }
  10. // return Arrays.stream(dp).max().getAsInt();

二分法 :

力扣

  1. class Solution {
  2. public int lengthOfLIS(int[] nums) {
  3. //tails数组是以当前长度连续子序列的最小末尾元素
  4. //如tail[0]是求长度为1的连续子序列时的最小末尾元素
  5. //例:在 1 6 4中 tail[0]=1 tail[1]=4 没有tail[2] 因为无法到达长度为3的连续子序列
  6. int tails[] = new int[nums.length];
  7. //注意:tails一定是递增的 因为看题解那个动画 我们最开始的那个元素一定找的是该数组里最小的 不然如果不是最小 由于我们需要连续 后面的数一定会更大(这样不好的原因是 数越小 我们找到一个比该数大的数的几率肯定会更大)
  8. int res = 0;
  9. for(int num:nums){
  10. //每个元素开始遍历 看能否插入到之前的tails数组的位置 如果能 是插到哪里
  11. int i = 0,j = res;
  12. while(i < j){
  13. int m = (i+j)/2;
  14. if(tails[m] < num) i = m+1;
  15. else j = m;
  16. }
  17. //如果没有到达j==res这个条件 就说明tail数组里只有部分比这个num要小 那么就把num插入到tail数组合适的位置即可 但是由于这样的子序列长度肯定是没有res长的 因此res不需要更新
  18. tails[i] = num;
  19. //j==res 说明目前tail数组的元素都比当前的num要小 因此最长子序列的长度可以增加了
  20. if(j == res) res ++;
  21. }
  22. return res;
  23. }
  24. }

发表评论

表情:
评论列表 (有 0 条评论,177人围观)

还没有评论,来说两句吧...

相关阅读

    相关 递增序列

    问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A\{5, 6, 7, 1, 2, 8\},则其...

    相关 递增序列

    给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。

    相关 递增序列

    最长递增子序列问题的求解   最长递增子序列问题是一个很基本、较常见的小问题,但这个问题的求解方法却并不那么显而易见,需要较深入的思考和较好的算法素养才能得出良好的算法。由