力扣11.23

1964. 找出到每个位置为止最长的有效障碍赛跑路线

你打算构建一些障碍赛跑路线。给你一个 下标从 0 开始 的整数数组 obstacles ,数组长度为 n ,其中 obstacles[i] 表示第 i 个障碍的高度。

对于每个介于 0 和 n - 1 之间(包含 0 和 n - 1)的下标 i ,在满足下述条件的前提下,请你找出 obstacles 能构成的最长障碍路线的长度:

  • 你可以选择下标介于 0 到 i 之间(包含 0 和 i)的任意个障碍。
  • 在这条路线中,必须包含第 i 个障碍。
  • 你必须按障碍在 obstacles 中的 出现顺序 布置这些障碍。
  • 除第一个障碍外,路线中每个障碍的高度都必须和前一个障碍 相同 或者 更高

返回长度为 n 的答案数组 ans ,其中 ans[i] 是上面所述的下标 i 对应的最长障碍赛跑路线的长度。

数据范围

  • n == obstacles.length
  • 1 <= n <= 105
  • 1 <= obstacles[i] <= 107

分析

本题数据范围比较大,因此不能使用n方做法,采用贪心+二分的方法,用q数组记录所有长度为i的最长非递减子序列中的最小值,这样可以尽可能多的构造非递减子序列,例如原数组为1,2,3,2

  • q=[1]
  • q=[1,2]
  • q=[1,2,3]
  • 2找到第一个大于2的下标,并将其替换q=[1,2,2],此时替换的位置就是最长序列的长度

代码

class Solution {
public:
    const static int N = 1e5 + 5;
    int dp[N]; 
    int q[N], tt = -1;
    void print() {
        for(int i = 0; i <= tt; i ++ ) cout << q[i] << " ";
        cout << endl;
    }
    vector<int> longestObstacleCourseAtEachPosition(vector<int>& obstacles) {
        int n = obstacles.size();
        vector<int> res;
        res.resize(n);
        for(int i = 0; i < n; i ++ ) {
            if(tt == -1 || obstacles[i] >= q[tt]) {
                q[++ tt] = obstacles[i];
                res[i] = tt + 1;
            }
            else {  
                int pos = upper_bound(q, q + tt, obstacles[i]) - q;
                res[i] = pos + 1;
                q[pos] = obstacles[i];
            }
        }
        return res;
    }
};

2111. 使数组 K 递增的最少操作次数

给你一个下标从 0 开始包含 n 个正整数的数组 arr ,和一个正整数 k 。

如果对于每个满足 k <= i <= n-1 的下标 i ,都有 arr[i-k] <= arr[i] ,那么我们称 arr 是 K 递增 的。

  • 比方说,arr = [4, 1, 5, 2, 6, 2] 对于 k = 2 是 K 递增的,因为:
    • arr[0] <= arr[2] (4 <= 5)
    • arr[1] <= arr[3] (1 <= 2)
    • arr[2] <= arr[4] (5 <= 6)
    • arr[3] <= arr[5] (2 <= 2)

但是,相同的数组 arr 对于 k = 1 不是 K 递增的(因为 arr[0] > arr[1]),对于 k = 3 也不是 K 递增的(因为 arr[0] > arr[3] )。
每一次 操作 中,你可以选择一个下标 i 并将 arr[i] 改成任意 正整数。

请你返回对于给定的 k ,使数组变成 K 递增的 最少操作次数 。

数据范围

  • 1 <= arr.length <= 105
  • 1 <= arr[i], k <= arr.length

分析

实际就是将原数组拆分为k个子数组,对每个子数组求他的最长非递减子序列,然后对于非递减子序列的元素就是最优的需要修改的,统计一下即可,这里求最长非递减子序列也是通过上题的贪心+二分计算

代码

class Solution {
public:
    const static int N = 1e5 + 5;
    int dp[N];
    int q[N], tt = -1;
    void print() {
        for(int i = 0; i <= tt; i ++ ) cout << q[tt] << " ";
        cout << endl;
    }
    int kIncreasing(vector<int>& arr, int k) {
        int res = 0;
        int n = arr.size();
        for(int i = 0; i <= k - 1; i ++ ) {
            tt = -1;
            int cnt = 0;
            for(int j = i; j < n; j += k) {
                cnt ++ ;
                if(tt == -1 || arr[j] >= q[tt]) q[++ tt] = arr[j];
                else {
                    int pos = upper_bound(q, q + tt, arr[j]) - q;
                    q[pos] = arr[j];
                }
            }
            res += cnt - (tt + 1);
        }
        return res;
    }
};

1626. 无矛盾的最佳球队

假设你是球队的经理。对于即将到来的锦标赛,你想组合一支总体得分最高的球队。球队的得分是球队中所有球员的分数 总和 。

然而,球队中的矛盾会限制球员的发挥,所以必须选出一支 没有矛盾 的球队。如果一名年龄较小球员的分数 严格大于 一名年龄较大的球员,则存在矛盾。同龄球员之间不会发生矛盾。

给你两个列表 scores 和 ages,其中每组 scores[i] 和 ages[i] 表示第 i 名球员的分数和年龄。请你返回 所有可能的无矛盾球队中得分最高那支的分数

数据范围

  • 1 <= scores.length, ages.length <= 1000
  • scores.length == ages.length
  • <= scores[i] <= 106
  • 1 <= ages[i] <= 1000

分析

首先将球员先按照年龄排序,再按照分数从小到大排序,令dp[i]表示选择第i个球员的最大分数,状态转移如下:

  • d p [ i ] = m a x ( d p [ i ] , d p [ j ] + s c o r e [ i ] ) dp[i]=max(dp[i],dp[j]+score[i]) dp[i]=max(dp[i],dp[j]+score[i])

代码

class Solution {
public:
    const static int N = 1005;
    int dp[N], agedp[N];
    struct node_ {
        int score, age;
        friend bool operator < (const node_ a, const node_ b) {
            if(a.age == b.age) return a.score < b.score;
            return a.age < b.age;
        }
    };
    vector<node_> nodes;
    int bestTeamScore(vector<int>& scores, vector<int>& ages) {
        int n = ages.size();
        for(int i = 0; i < n; i ++ ) {
            nodes.push_back({scores[i], ages[i]});
        }
        sort(nodes.begin(), nodes.end());
        for(int i = 0; i < n; i ++ ) {
            dp[i] += nodes[i].score;
            for(int j = 0; j < i; j ++ ) {
                if(nodes[j].score <= nodes[i].score) dp[i] = max(dp[i], dp[j] + nodes[i].score);
            }
        }
        int res = 0;
        for(int i = 0; i < n; i ++ ) res = max(res, dp[i]);
        return res;
    }
};

54. 俄罗斯套娃信封问题

给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。

当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。

请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

注意:不允许旋转信封。

数据范围

  • 1 <= envelopes.length <= 105
  • envelopes[i].length == 2
  • 1 <= wi, hi <= 105

分析

先按w升序,再按h降序,按h降序保证了w相同的信封只能选一个,然后对h求最长上升子序列就行,此时就满足h递增且w递增

代码

class Solution {
public:
    const static int N = 1e5 + 5;
    struct node_ {
        int a, b;
        friend bool operator < (const node_ &a, const node_ &b) {
            if(a.a == b.a) return a.b > b.b;
            return a.a < b.a;
        }
    };
    int n;
    node_ q[N];
    int tt = -1;
    vector<node_> envelopes;
    int find(node_ x) {
        int l = 0, r = tt;
        while(l < r) {
            int mid = (l + r) >> 1;
            if(q[mid].b < x.b) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    int maxEnvelopes(vector<vector<int>>& envs) {
        n = envs.size();
        for(int i = 0; i < n; i ++ ) envelopes.push_back({envs[i][0], envs[i][1]});
        sort(envelopes.begin(), envelopes.end());
        for(int i = 0; i < n; i ++ ) {
            int a = envelopes[i].a, b = envelopes[i].b;
            if(tt == -1 || b > q[tt].b) q[++ tt] = {a, b};
            else {
                int pos = find({a, b});
                q[pos] = {a, b};
            }
        }
        return tt + 1;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921723.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测试人员--如何区分前端BUG和后端BUG

在软件测试中&#xff0c;发现一个BUG并不算难&#xff0c;但准确定位它的来源却常常让测试人员头疼。是前端页面的问题&#xff1f;还是后台服务的异常&#xff1f;如果搞错了方向&#xff0c;开发人员之间的沟通效率会大大降低&#xff0c;甚至导致问题久拖不决。 那么&#…

嵌入式:Flash的分类以及Jlink/J-flash的编程支持

相关阅读 嵌入式https://blog.csdn.net/weixin_45791458/category_12768532.html?spm1001.2014.3001.5482 常见的Flash大致可以分为以下大类&#xff1a; Serial Nor FlashSerial Nand FlashParallel Nor FlashParallel Nand FlashSerial EEPROM Serial Nor Flash 介绍 Se…

【Linux系统编程】第五十弹---构建高效单例模式线程池、详解线程安全与可重入性、解析死锁与避免策略,以及STL与智能指针的线程安全性探究

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、将日志加到线程池 1.1、Thread类 1.2、ThreadPool类 1.2.1、HandlerTask() 1.2.2、其他公有成员函数 1.3、主函数 2、…

基于SSM的作业批改系统+LW示例参考

1.项目介绍 功能模块&#xff1a;管理员&#xff08;学生管理、教师管理、作业信息管理、作业提交管理、作业批改管理等&#xff09;、学生&#xff08;个人信息管理、作业提交、作业查看等&#xff09;、教师&#xff08;个人中心、作业创建、作业批改等&#xff09;技术选型…

RabbitMQ高可用延迟消息惰性队列

目录 生产者确认 消息持久化 消费者确认 TTL延迟队列 TTL延迟消息 惰性队列 生产者确认 生产者确认就是&#xff1a;发送消息的人&#xff0c;要确保消息发送给了消息队列&#xff0c;分别是确保到了交换机&#xff0c;确保到了消息队列这两步。 1、在发送消息服务的ap…

嵌入式面试八股文(十)·RS485特性分析、CAN硬件同步和再同步遵从规则、SPI四种工作模式、错误帧基本概念

目录 1. 相较于传统的RS232接口&#xff0c;RS485的接口特性有哪些&#xff1f; 2. 在CAN接口协议中硬件同步和再同步需要遵从哪些规则&#xff1f; 3. 为什么位错误不能用于帧间隔&#xff1f; 4. SPI四种工作模式&#xff1f; 5. 关于错误帧&#xff0c;基本概念&a…

librdns一个开源DNS解析库

原文地址&#xff1a;librdns一个开源DNS解析库 – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 介绍 librdns是一个开源的异步多功能插件式的解析器&#xff0c;用于DNS解析。 源代码地址&#xff1a;GitHub - vstakhov/librdns: Asynchrono…

cookie反爬----普通服务器,阿里系

目录 一.常见COOKIE反爬 普通&#xff1a; 1. 简介 2. 加密原理 二.实战案例 1. 服务器响应cookie信息 1. 逆向目标 2. 逆向分析 2. 阿里系cookie逆向 1. 逆向目标 2. 逆向分析 实战&#xff1a; 无限debugger原理 1. Function("debugger").call() 2. …

大数据新视界 -- 大数据大厂之 Impala 性能优化:跨数据中心环境下的挑战与对策(上)(27 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

width设置100vh但出现横向滚动条的问题

在去做flex左右固定,中间自适应宽度的布局时, 发现这样一个问题: 就是我明明是宽度占据整个视口, 但是却多出了横向的滚动条 效果是这样的 把width改成100%,就没有滚动条了 原因: body是有默认样式的, 会有一定的默认边距, 把默认边距清除就是正常的了 同时, 如果把高度设…

百度在下一盘大棋

这两天世界互联网大会在乌镇又召开了。 我看到一条新闻&#xff0c;今年世界互联网大会乌镇峰会发布“2024 年度中国互联网企业创新发展十大典型案例”&#xff0c;百度文心智能体平台入选。 这个智能体平台我最近也有所关注&#xff0c;接下来我就来讲讲它。 百度在下一盘大棋…

探索 RocketMQ:企业级消息中间件的选择与应用

一、关于RocketMQ RocketMQ 是一个高性能、高可靠、可扩展的分布式消息中间件&#xff0c;它是由阿里巴巴开发并贡献给 Apache 软件基金会的一个开源项目。RocketMQ 主要用于处理大规模、高吞吐量、低延迟的消息传递&#xff0c;它是一个轻量级的、功能强大的消息队列系统&…

Android 基于Camera2 API进行摄像机图像预览

前言 近期博主准备编写一个基于Android Camera2的图像采集并编码为h.264的应用&#xff0c;准备分为三个阶段来完成&#xff0c;第一阶段实现Camera2的摄像机预览&#xff0c;第二阶段完成基于MediaCodec H.264编码&#xff0c;第三阶段完成基于MediaCodec H.264解码,针对不同…

QT 线程 QThread QT5.12.3环境 C++实现

一、线程 QT主线程称为GUI线程&#xff0c;负责初始化界面并监听事件循环&#xff0c;并根据事件处理做出界面上的反馈。如果把一些比较复杂或者费时的操作放在主线程中&#xff0c;界面就会出现卡顿或者无响应的现象。一般主线程负责影响界面上的操作&#xff0c; 子线程负责负…

【LLM】一文学会SPPO

博客昵称&#xff1a;沈小农学编程 作者简介&#xff1a;一名在读硕士&#xff0c;定期更新相关算法面试题&#xff0c;欢迎关注小弟&#xff01; PS&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟沈小农&#xff0c;希望我的文章能帮助到你。欢迎大家在…

Vue3-后台管理系统

目录 一、完成项目历程 1、构建项目 2、项目的自定义选项 3、 封装组件 4、配置对应页面的路由 5、从后端调接口的方式 二、引入Element Plus、Echarts、国际化组件 1、Element Plus安装 2、Echarts安装 3、国际化 三、介绍项目以及展示 1、项目是基于Vue3、Element …

C0030.Clion中运行提示Process finished with exit code -1073741515 (0xC0000135)解决办法

1.错误提示 2.解决办法 添加环境变量完成之后&#xff0c;重启Clion软件&#xff0c;然后就可以正常调用由mingw编译的opencv库了。

【es6进阶】vue3中的数据劫持的最新实现方案的proxy的详解

vuejs中实现数据的劫持,v2中使用的是Object.defineProperty()来实现的&#xff0c;在大版本v3中彻底重写了这部分&#xff0c;使用了proxy这个数据代理的方式&#xff0c;来修复了v2中对数组和对象的劫持的遗留问题。 proxy是什么 Proxy 用于修改某些操作的默认行为&#xff0…

Python浪漫之画明亮的月亮

目录 1、效果展示 2、完整版代码 1、效果展示 2、完整版代码 import turtledef draw_moon():# 设置画布turtle.bgcolor("black") # 背景颜色为黑色turtle.speed(10) # 设置绘制速度# 绘制月亮的外圈turtle.penup()turtle.goto(0, -100) # 移动到起始…

《线性代数的本质》

之前收藏的一门课&#xff0c;刚好期末复习&#xff0c;顺便看一看哈哈 课程链接&#xff1a;【线性代数的本质】合集-转载于3Blue1Brown官方双语】 向量究竟是什么 线性代数中最基础、最根源的组成部分就是向量&#xff0c;需要先明白什么是向量 不同专业对向量的看法 物理专…