题解 | #牛牛的装球游戏#

最长严格上升子数组(一)

http://www.nowcoder.com/practice/78889543865f4aa380fa69e641ad9889

首先想好算法,一看最长上升子序列,那么比较脑子里应该出现几个dp式子: 接下来一看要求:空间复杂度 O (n) ,时间复杂度 O (n) 好家伙必须要on的复杂度 那么可以尝试结合其他算法去优化一个比较直接的dp,那么咱们首选二分!

二分的思路如下:

  1. 先定义边界,l = 0, r = len, 其中len是q数组的长度
  2. 然后确定check函数, 可以先找到不等式中c < x ≤ a ≤ b的c 通过q[r + 1] = a[i]来将x覆盖a的值 同时也要考虑算法1的情况1, 需要扩大q数组的长度
  3. 即r + 1 > len时, 表示超出了二分边界,这时就要len ++更新q的长度
  4. 时间复杂度
  5. 遍历每个数是 O(n)
  6. 遍历q数组每个数, 找到一个最大的小于当前数x的数O(logn)
  7. 因此时间复杂度是 O(nlogn) C++ 代码
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 1e5 + 5;

int a[maxn], f[maxn];
int cnt;

inline int find(int x) {
    int l = 1, r = cnt; 
    while(l < r) {
        int mid = l + r >> 1;
        if(f[mid] >= x) r = mid;
        else l = mid + 1;
    }

    return l;
}

int main(void) {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);

    f[++cnt] = a[1];
    for(int i = 2; i <= n; i ++) 
        if(a[i] > f[cnt]) f[ ++ cnt] = a[i];
        else {
            int tmp = find(a[i]);
            f[tmp] = a[i]; 
        }

    printf("%d\n", cnt);

    return 0;
}

全部评论
你这题解第一个样例都过不去,是不是贴错了
点赞 回复 分享
发布于 2023-02-20 17:29 山东

相关推荐

不愿透露姓名的神秘牛友
今天 15:43
点赞 评论 收藏
分享
专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
10-17 16:07
门头沟学院 Java
牛牛大你18号:在汇报,突然弹出来,,领导以为我在准备跳槽,刚从领导办公室谈心出来
点赞 评论 收藏
分享
评论
4
3
分享
牛客网
牛客企业服务