java---二分单调队列---最长上升子序列的长度2(每日一道算法2022.10.16)

注意事项:
建议先理解基础版的写法:java—线性dp—最长上升子序列的长度1

题目:
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少

第一行包含整数 N
第二行包含 N 个整数,表示完整序列
输出一个整数,表示最大长度

数据范围
1 ≤ N ≤ 100000,
−10e9 ≤ 数列中的数 ≤ 10e9

输入:
7
3 1 2 1 8 5 6
输出:
4
public class 线性dp_最长上升子序列2 {
    public static int N = 10, n;
    public static int[] a = new int[N];
    public static Scanner in = new Scanner(System.in);

    public static void main(String[] args) {
        //读入
        n = in.nextInt();
        for (int i = 0; i<n; i++) a[i] = in.nextInt();

        base();
    }

    public static void base() {
        int[] q = new int[N];
        int len = 0;
        //遍历每个元素a[i],使用"向右"查找的二分来找到q中最后一个比a[i]小的值的下标r,将其后一位r+1替换为当前值
        for (int i = 0; i<n; i++)  {
            int l = 0, r = len;
            while (l < r) {
                int mid = (l+r+1) / 2;
                //这里对二分的模板做了一点点微调,正常应该是<=但这里用的是<
                //因为要找到必须小于a[i]的值的下标r,更新r+1才能保证单调队列的绝对上升
                if (q[mid] < a[i]) l = mid;	
                else r = mid - 1;
            }
            //不关心q内的元素到底是什么,只要保证size(子序列长度)最大即可
            len = Math.max(len, r + 1);
            q[r + 1] = a[i];
        }

        System.out.println(len);
    }
}

思路:
求出严格单调的上升队列即可,不需要关心其中到底有什么元素,但这也就导致这种方法无法得到这个最长上升队列,如果想得到还是用这种方法较好:java—线性dp—拿到最长上升子序列

声明:
算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值