Leetcode第 217 场周赛(思维量比较大)

2023-05-16

Leetcode第 217 场周赛

比赛链接:点这里

做完前两题我就知道今天的竞赛我已经结束了

这场比赛思维量还是比较大的。

1673. 找出最具竞争力的子序列

题目

给你一个整数数组 nums 和一个正整数 k ,返回长度为 k 且最具 竞争力nums 子序列。

数组的子序列是从数组中删除一些元素(可能不删除元素)得到的序列。

在子序列 a 和子序列 b 第一个不相同的位置上,如果 a 中的数字小于 b 中对应的数字,那么我们称子序列 a 比子序列 b(相同长度下)更具 竞争力 。 例如,[1,3,4][1,3,5] 更具竞争力,在第一个不相同的位置,也就是最后一个位置上, 4 小于 5

示例 1:

输入:nums = [3,5,2,6], k = 2
输出:[2,6]
解释:在所有可能的子序列集合 {[3,5], [3,2], [3,6], [5,2], [5,6], [2,6]} 中,[2,6] 最具竞争力。

示例 2:

输入:nums = [2,4,3,3,5,4,9,6], k = 4
输出:[2,3,3,4]

提示:

  • 1 < = n u m s . l e n g t h < = 1 0 5 1 <= nums.length <= 10^5 1<=nums.length<=105
  • 0 < = n u m s [ i ] < = 1 0 9 0 <= nums[i] <= 10^9 0<=nums[i]<=109
  • 1 < = k < = n u m s . l e n g t h 1 <= k <= nums.length 1<=k<=nums.length

思路

比赛时想到了单调栈,但是不熟不敢写( 还得练练。。

随便写了一通居然过了。

思路是找到数组中的最小值mi,那么最后的结果中肯定有这个值,如果mi所在的位置p之后的元素个数不足k个了,那么p之后的元素肯定都是要的,因为没有比它们更小的了,但是此时元素个数不够,那么就需要在p之前的元素的中找剩下的元素。这不就是个子问题么,直接递归完事儿。

代码

class Solution {
public:
    vector<int> vis;
    void helper(vector<int>& nums, int k, int l, int r){
        if(l > r || k <= 0) return;
        
        // 最小值
        int p;
        int minn = 0x3f3f3f3f;
        for(int i = l; i <= r; i++){
            if(minn > nums[i]){
                minn = nums[i];
                p = i;
            }
        }
        vis[p] = 1;
        int t = r-p;
        // 剩下元素个数大于k,直接在k后面找剩下的元素,因为此位置一定是最小的。
        if(t >= k) {
            helper(nums, k-1, p+1, r);
        }
        else {
            //剩下元素没有k个
            for(int i = p+1; i <= r; i++) vis[i] = 1;
            helper(nums, k-t-1, l, p-1);
        }
    }
    vector<int> mostCompetitive(vector<int>& nums, int k) {
        if(!nums.size() || nums.size() < k) return vector<int>();
        if(k == nums.size()) return nums;
        
        vector<int> t = nums;
        sort(t.begin(), t.end());
        if(t == nums){
            return vector<int> (nums.begin(), nums.begin()+k);
        }
        
        vis = vector<int> (nums.size(), 0); //记录答案
        
        helper(nums, k, 0, nums.size()-1);
        vector<int> ans;
        for(int i = 0; i < nums.size(); i++){
            if(vis[i]) ans.push_back(nums[i]);
        }
        return ans;
    }
};

正解

单调栈维护栈顶元素比当前元素小。

弹栈当且仅当栈顶元素比当前元素大并且保证栈中元素加上剩余元素能够凑够k个。

巨坑:vector .size()方法一定要加(int), 这个错误不好找,也想不到。

在这里插入图片描述

以示警醒。

代码逻辑还是比较简单的。

代码

class Solution {
public:
    vector<int> mostCompetitive(vector<int>& nums, int k) {
        vector<int> st;
        for(int i = 0; i < nums.size(); i++){
            int c = nums[i];
            while(!st.empty() && st.back() > c &&  k - (int)st.size() + 1 <= (int)nums.size() - i) st.pop_back();
            st.push_back(c);
        }

        while(st.size() > k) st.pop_back();
        return st;
    }
};

PS:这道题跟402. 移掉K位数字这道有异曲同工之妙,不同点在于一个是删除k个数,一个是留下k个数,但是思路大题一致,可以对比着来学。是的,做过的题记不住。ε=(´ο`*)))

1674. 使数组互补的最少操作次数

题目

给你一个长度为 偶数 n 的整数数组 nums 和一个整数 limit 。每一次操作,你可以将 nums 中的任何整数替换为 1limit 之间的另一个整数。

如果对于所有下标 i下标从 0 开始),nums[i] + nums[n - 1 - i] 都等于同一个数,则数组 nums互补的 。例如,数组 [1,2,3,4] 是互补的,因为对于所有下标 inums[i] + nums[n - 1 - i] = 5

返回使数组 互补最少 操作次数。

示例 1:

输入:nums = [1,2,4,3], limit = 4
输出:1
解释:经过 1 次操作,你可以将数组 nums 变成 [1,2,2,3](加粗元素是变更的数字):
nums[0] + nums[3] = 1 + 3 = 4.
nums[1] + nums[2] = 2 + 2 = 4.
nums[2] + nums[1] = 2 + 2 = 4.
nums[3] + nums[0] = 3 + 1 = 4.
对于每个 i ,nums[i] + nums[n-1-i] = 4 ,所以 nums 是互补的。

示例 2:

输入:nums = [1,2,2,1], limit = 2
输出:2
解释:经过 2 次操作,你可以将数组 nums 变成 [2,2,2,2] 。你不能将任何数字变更为 3 ,因为 3 > limit 。

示例 3:

输入:nums = [1,2,1,2], limit = 2
输出:0
解释:nums 已经是互补的。

提示:

  • n = = n u m s . l e n g t h n == nums.length n==nums.length
  • 2 < = n < = 1 0 5 2 <= n <= 10^5 2<=n<=105
  • 1 < = n u m s [ i ] < = l i m i t < = 1 0 5 1 <= nums[i] <= limit <= 10^5 1<=nums[i]<=limit<=105
  • n n n 是偶数。

思路

完全没有思路,题刷得还是太少了啊

差分+前缀和

首先我们知道答案最大是 n n n, 这是将所有的数字都改了的情况。

假设数组中互补的两元素为 A A A B B B

我们用 d e l t a [ i ] delta[i] delta[i] 表示将 A + B A+B A+B改为 i i i时需要的操作次数,那么就可以分为以下五种情况:

  • 2 < = i < = m i n ( A , B ) 2<=i<=min(A, B) 2<=i<=min(A,B): 需要两次操作
  • m i n ( A , B ) + 1 < = i < = m a x ( A , B ) + 1 min(A, B)+1<=i<=max(A, B) + 1 min(A,B)+1<=i<=max(A,B)+1: 需要一次操作
  • i = = A + B i == A+B i==A+B: 不需要操作
  • A + B + 1 < = i < = l i m i t + m a x ( A , B ) A+B+1<=i<=limit + max(A, B) A+B+1<=i<=limit+max(A,B): 需要一次操作
  • i > l i m i t + m a x ( A , B ) i > limit + max(A, B) i>limit+max(A,B): 需要两次操作

但是知道了这么多种情况,怎么来表示他们之间的变化以及求和呢?

答案是使用差分数组,只需要改变被改变区间的边界的两个值,就可以在 O ( n ) O(n) O(n)的时间里求和。

代码

class Solution {
public:
    int minMoves(vector<int>& nums, int limit) {
        vector<int> delta(limit*2+20, 0);
        int n = nums.size();
        delta[0] = n; //开始为n次操作
        unordered_map<int, int> freq;
        for(int i = 0; i < n/2; i++){
            int sums = nums[i] + nums[n-i-1];
            int lo = 1 + min(nums[i], nums[n-i-1]);
            int hi = limit + 1 + max(nums[i], nums[n-i-1]);

            // 差分
            delta[lo] --;
            delta[sums]--;
            delta[sums+1] ++;
            delta[hi]++;
        }

        //求和
        for(int i = 1; i <= limit*2; i++) delta[i] += delta[i-1];
        int ans = 0x3f3f3f3f;
        for(int i = 1; i <= limit*2; i++){
            ans = min(ans, delta[i]);
        }
        return ans;
    }
};

1675. 数组的最小偏移量

题目

给你一个由 n 个正整数组成的数组 nums

你可以对数组的任意元素执行任意次数的两类操作:

  • 如果元素是偶数,除以 2 2 2
    • 例如,如果数组是 [1,2,3,4] ,那么你可以对最后一个元素执行此操作,使其变成 [1,2,3, 2]
  • 如果元素是奇数,乘上 2 2 2
    • 例如,如果数组是 [1,2,3,4] ,那么你可以对第一个元素执行此操作,使其变成 [2,2,3,4]

数组的 偏移量 是数组中任意两个元素之间的 最大差值

返回数组在执行某些操作之后可以拥有的 最小偏移量

示例 1:

输入:nums = [1,2,3,4]
输出:1
解释:你可以将数组转换为 [1,2,3,2],然后转换成 [2,2,3,2],偏移量是 3 - 2 = 1

示例 2:

输入:nums = [4,1,5,20,3]
输出:3
解释:两次操作后,你可以将数组转换为 [4,2,5,5,3],偏移量是 5 - 2 = 3

示例 3:

输入:nums = [2,10,8]
输出:3

提示:

  • n = = n u m s . l e n g t h n == nums.length n==nums.length
  • 2 < = n < = 105 2 <= n <= 105 2<=n<=105
  • 1 < = n u m s [ i ] < = 1 0 9 1 <= nums[i] <= 10^9 1<=nums[i]<=109

思路

又是智商被吊打的一题

优先队列

我们考虑维护大根堆,将所有数先化为最大的形式(也就是奇数 ∗ 2 *2 2),加入大根堆,维护 m i mi mi 表示当前堆的最小值。

之后我们不断地取出堆顶,也就是当前堆最大的数,除 2 2 2,重新加入大根堆,此过程中不断更新答案。

当堆顶为奇数时,就说明不能再除以 2 2 2,最大值不可能再缩小,答案也就不会再被缩小。

代码

class Solution {
public:
    int minimumDeviation(vector<int>& nums) {
        priority_queue<int> q; //大根堆
        int mi = INT_MAX;
        for(auto x : nums){
            if(x&1) x <<= 1; //奇数乘2加入
            q.push(x);
            mi = min(mi, x);
        }
        int ans = INT_MAX;
        while(1){
            auto x = q.top();
            q.pop();
            ans = min(ans, x-mi);
            if(x&1) break; //最大值奇数直接退出
            x >>= 1;
            q.push(x);
            mi = min(x, mi); //维护mi为当前堆中的最小值
        }
        return ans;
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Leetcode第 217 场周赛(思维量比较大) 的相关文章

  • Python【列表】

    文章目录 1 列表的方法及注释2 其他修改列表的办法2 列表推导式3 列表的切片4 列表转换4 1 字符串转列表 xff1a 4 2 列表转字符串 list 列表 是一个可变序列 1 列表的方法及注释 列表的方法注释append x 将元素
  • FTP的port模式和pasv模式

    FTP的port模式和pasv模式 FTP具有两种模式 xff0c 分别是port模式 也叫主动模式 和pasv模式 也叫被动模式 主动模式 主动模式的FTP是指服务器主动连接客户端的数据端口 xff0c 可以理解为服务端主动给客户端传输文
  • shell for循环多个变量

    1 使用花括号 var1 var2 var3 a 61 span class token string 34 apple 34 span span class token punctuation span b 61 span class t
  • shell 基本运算符

    文章目录 1 算数运算2 关系运算符3 布尔运算符4 逻辑运算符5 字符串运算符6 文件测试运算符知识点 1 算数运算 方法一 sum1 61 96 expr 3 span class token operator 43 span 5 96
  • Dockerfile简介

    1 什么是dockerfile Dockerfile是一个包含用于组合映像的命令的文本文档 可以使用在命令行中调用任何命令 Docker通过读取Dockerfile中的指令自动生成映像 docker build命令用于从Dockerfile
  • 容器通信之跨链接通信

    前言 同一主机下搭建容器应用栈的环境 xff0c 只需要完成容器互联来实现容器间的通信即可 xff0c 这里采用docker run link选项建立容器间的互联关系 docker官方已不推荐使用docker run link来链接2个容器
  • Linux进程间通信

    1 unix域套接字 域套接字 xff1a 1 只能用于同一设备上不同进程之间的通信 xff1b 2 效率高于网络套接字 域套接字仅仅是复制数据 xff0c 并不走协议栈 xff1b 3 可靠 xff0c 全双工 xff1b 2 IP套接字
  • 什么是API

    1 什么是API API是Application Programming Interface xff08 应用程序接口 xff09 的缩写 是一些预先定义的函数 xff0c 目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力
  • FreeRTOS(二)任务基础知识

    一 前后台系统与RTOS 前后台系统 61 死循环 xff08 通常为1个 xff09 43 中断服务程序 xff08 通常为若干个 xff09 应用程序是一个无限循环 xff0c 循环中调用 API 函数完成所需的操作 xff0c 这个大
  • SBUS协议(20200210)

    最近看到很多sbus协议 xff0c 就专门搜集了一些资料学习一下 1 介绍 SBUS是一个接收机串行总线输出 xff0c 通过这根总线 xff0c 可以获得遥控器上所有通道的数据 目前很多模型及无人机电子设备都支持SBUS总线的接入 使用
  • 【openmv专题】串口通信

    这篇文章主要讲述openmv串口通信过程中会出现错位 xff0c 因缓存空间不足带来的串口报错问题 xff0c 直接进入正题 xff1a 串口通信有同步和异步之分 xff0c 而openmv用的是异步通信 xff0c 需要有缓存区 xff0
  • FreeRTOS任务上下文切换与任务状态切换的区别及联系

    FreeRTOS 中的任务上下文切换和任务状态切换是两个不同的概念 1 任务状态切换是指任务从一种状态切换到另一种状态 FreeRTOS 中的任务状态包括就绪态 阻塞态和运行态 当任务从就绪态切换到运行态时 xff0c 任务开始执行 xff
  • XGBOD:用无监督表示学习改进有监督离群点检测

    XGBOD Improving Supervised Outlier Detection with Unsupervised Representation Learning 论文链接 xff1a https www andrew cmu e
  • 小觅S系列相机运行vins-mono(轨迹飘飞解决版)

    小觅S系列相机运行vins mono xff08 轨迹飘飞解决版 xff09 1 SDK驱动2 获得相机标定数据3 下载MYNT EYE VINS Sample4 运行 前期准备 xff1a 安装并成功运行VINS MONO 1 SDK驱动
  • 嵌入式第0部分:嵌入式工程师完全学习指南

    一 什么是嵌入式 xff08 一 xff09 定义 xff1a 传统定义 xff08 狭义嵌入式 xff09 xff1a 嵌入式系统是以应用为中心 xff0c 以计算机技术为基础 xff0c 并且软硬件课裁剪 xff0c 适用于应用系统对功
  • 【SLAM 十四讲】---第七讲、视觉里程计

    第七讲 视觉里程计
  • Vscode配置git

    1 Git介绍和安装 Git是什么 Git是目前世界上最先进的分布式版本控制系统 xff08 没有之一 xff09 简单来说 它是控制项目版本的一个工具 我们可以利用Git进行多人协作和代码备份等工作 下载git xff08 64bit w
  • Xshell连接虚拟机Ubantu失败解决办法(主机和虚拟机能够互ping的前提)

    主机和虚拟机互ping 在主机命令行里输入ipconfig指令 xff0c 查询主机ip地址 xff0c 在虚拟机Ubantu终端里输入ping 主机ip地址 xff0c ping通后 xff0c 按ctrl 43 c停止 在虚拟机Uban
  • windows 11系统安装

    安装前注意事项 1 准备8G或8G以上U盘 xff08 32G以内 xff09 2 安装系统前备份好个人需要数据 xff08 制作U盘会格式化U盘 xff0c U盘内的重要文件也要事先备份好 xff09 3 预装office的务必记住自己激
  • docker 权限问题 Got permission denied while trying to connect to the Docker daemon socket at

    一 前言 docker安装完成 xff0c 一般用户没有权限启动docker服务 xff0c 只能通过sudo来通过root用户权限来启动docker xff0c 此时对于一般用户而言 xff0c 需要执行docker ps或者docker

随机推荐

  • Neo4j(七)——创建新数据库(如何在Neo4j中创建新数据库)

    方法一 xff1a 找到neo4j安装目录 xff0c 编辑conf文件夹中的neo4j conf 找到dbms active database 61 xff0c 将下图中的graph db用其他名称替换 xff0c 并解除注释 xff08
  • python VScode使用gitlab简单使用流程

    一 下载安装软件 1 安装好vscode xff0c 如未安装 xff0c 下载并且安装 https code visualstudio com Download 2 安装git windows客户端 https git scm com d
  • keil5工程函数无法跳转到函数定义解决方法

    问题描述 在使用keil查看工程代码时 xff0c 进行函数的跳转 xff0c 跳转不成功并提示以下错误 这是因为在编译工程的时候少勾选了一个选项 xff0c 按下以下方式勾选上然后重新Rebuild一下工程就好了
  • Codeforces D. Prefix-Suffix Palindrome

    Codeforces D Prefix Suffix Palindrome 题解 xff1a 和D1相同 xff0c 区别是找中间的回文串要压缩时间 xff0c 用到了马拉车算法 xff08 算法介绍在下面 xff1a span class
  • codeforces 1326 E.Bombs

    codeforces 1326 E Bombs 题意 xff1a 给定 1 n 1 n 1 n 的排列p q xff0c 将
  • Educational Codeforces Round 84 题解

    Educational Codeforces Round 84 题解 A Sum of Odd Integers 题意 xff1a n n n 是否能表示为 k k k 个不同的正奇
  • codeforces 1332 E - Height All the Same(组合数学、奇偶性)

    codeforces 1332 E Height All the Same 组合数学 奇偶性 题意 xff1a 现在有一个 n m n m n m 的方格 xff0c 第 i
  • codeforces 1330 C.D.题解

    codeforces 1330 C D 题解 Dreamoon Likes Coloring 题意 xff1a 给 n lt 61 100000 n lt 61 100000 n lt 61
  • LeetCode数独问题中Bitset的巧妙用处

    LeetCode数独问题中Bitset的巧妙用处 36 有效的数独 判断一个 9x9 的数独是否有效 只需要根据以下规则 xff0c 验证已经填入的数字是否有效即可 数字 1 9 在每一行只能出现一次 数字 1 9 在每一列只能出现一次 数
  • Morris 遍历

    Morris 遍历 中序遍历 前言 我们在中序遍历的时候 一定先遍历左子树 然后遍历当前节点 最后遍历右子树 在常规方法中 我们用递归回溯或者是栈来保证遍历完左子树可以再回到当前节点 但这需要我们付出额外的空间代价 我们需要用一种巧妙地方法
  • 第九届蓝桥杯c/c++A组省赛题解

    分数 题目 1 1 43 1 2 43 1 4 43 1 8 43 1 16 43 每项是前一项的一半 xff0c 如果一共有20项 求这个和是多少 xff0c 结果用分数表示出来 类似 xff1a 3 2 当然 xff0c 这只是加了前2
  • Ltp介绍及实践(20200925)

    Ltp中源代码和模型包括 xff1a 中文分词 词性标注 未登录词识别 依存句法 语义角色标注几个模块 目录 1 标注集合 分词标注集 词性标注集 命名实体识别标注集 依存句法关系 语义角色类型 2 快速使用 载入模型 分句 用户自定义词典
  • 第十一届蓝桥杯省赛C/C++B组题解

    试题 A 跑步训练 本题总分 xff1a 5 分 题目 问题描述 小明要做一个跑步训练 初始时 xff0c 小明充满体力 xff0c 体力值计为 10000 如果小明跑步 xff0c 每分钟损耗 600 的体力 如果小明休息 xff0c 每
  • codeforces Round680 C. Division 题解

    codeforces Round680 C Division 题解 题目 Oleg s favorite subjects are History and Math and his favorite branch of mathematic
  • Codeforces Round #677 (Div. 3) 题解

    Codeforces Round 677 Div 3 题解 A Boring Apartments 题目 题解 简单签到题 xff0c 直接数 xff0c 小于这个数的 43 10 43 10 43 1 0 代码 span class to
  • Leetcode 327. 区间和的个数 (前缀和 + 离散化 + 树状数组)

    Leetcode 327 区间和的个数 前缀和 43 离散化 43 树状数组 题目 题意 有多少个连续的子数组 xff0c 其和在 l o w e r
  • 01 Trie 专题

    01 Trie 专题 异或最大值 The xor largest pair 题意 xff1a 异或最大值的模板 一个数和一个序列中一个数的异或最大值是多少 xff1f 要支持询问 思路 考虑把序列插入 xff0c 构建一个 Trie tex
  • DFS序专题

    牛客专题之DFS序 简介 dfs序 每个节点在dfs深度优先遍历中的进出栈的时间序列 xff0c 也就是tarjan算法中的dfn数组 画个图理解一下 xff1a 这棵树的dfs序 xff1a 1 3 2 4 2 5 6 7 6 5 1 那
  • 牛客编程巅峰赛S2第4场题解

    牛客编程巅峰赛S2第4场 牛牛摆玩偶 题目描述 牛牛有 n 2 n 1 0
  • Leetcode第 217 场周赛(思维量比较大)

    Leetcode第 217 场周赛 比赛链接 xff1a 点这里 做完前两题我就知道今天的竞赛我已经结束了 这场比赛思维量还是比较大的 1673 找出最具竞争力的子序列 题目 给你一个整数数组 nums 和一个正整数 k xff0c 返回长