D349周赛:注意题目提示里,数据范围隐含的算法复杂度提示

news2025/2/11 20:43:56

文章目录

    • 6470.既不是最大值也不是最小值
      • 完整版
      • 为什么两个for循环时间复杂度还是不变的
    • 6465.执行子串操作后的字典序最小字符串
      • 思路
      • 最开始的写法
        • 题意理解的问题
      • 修改版
        • 'a'必须单独拿出来的原因
    • 6449.收集巧克力
      • 思路
        • 注意提示信息
      • 完整版
      • 补充:由数据范围反推算法复杂度及算法内容

6470.既不是最大值也不是最小值

  • 同一数组遍历两遍,时间复杂度还是O(n)
  • erase操作会增加额外的时间开销

给你一个整数数组 nums ,数组由 不同正整数 组成,请你找出并返回数组中 任一 既不是 最小值 也不是 最大值 的数字,如果不存在这样的数字,返回 -1

返回所选整数。

示例 1:

输入:nums = [3,2,1,4]
输出:2
解释:在这个示例中,最小值是 1 ,最大值是 4 。因此,23 都是有效答案。

示例 2:

输入:nums = [1,2]
输出:-1
解释:由于不存在既不是最大值也不是最小值的数字,我们无法选出满足题目给定条件的数字。因此,不存在答案,返回 -1

完整版

  • 主要是注意,这种删除nums元素的写法,删除了max的索引之后,min的索引值也会变化,因此需要进行前后索引值的判断!
  • erase的用法是nums.erase(nums.begin()+maxIndex);传入的是迭代器
class Solution {
public:
    int findNonMinOrMax(vector<int>& nums) {
        int max = nums[0];
        int maxIndex = 0;
        int min = nums[0];
        int minIndex = 0;
        
        //测试用例输入[1]的时候,预期输出是-1,后期修改
        if(nums.size()==1){
            return -1;
        }
        
        for(int i=0; i<nums.size(); i++){
            if(nums[i] > max){
                max = nums[i];
                maxIndex = i;
            }
            if(nums[i] < min){
                min = nums[i];
                minIndex = i;
            }
        }

        // 如果最大值在最小值之前,先删除最大值,然后再删除最小值,注意删除最大值后最小值索引需要减一
        if(maxIndex < minIndex) {
            nums.erase(nums.begin() + maxIndex);
            nums.erase(nums.begin() + minIndex - 1);
        } 
        else {
            // 如果最小值在最大值之前,先删除最小值,然后再删除最大值
            nums.erase(nums.begin() + minIndex);
            nums.erase(nums.begin() + maxIndex - 1);
        }

        if(!nums.empty()){
            return nums[0];
        }
        else
            return -1;    
        
    }
};

这种写法还是写复杂了,时间复杂度是O(n),实际上用两个for循环时间复杂度也是O(n)

class Solution {
public:
    int findDifferentNumber(vector<int>& nums) {
        int min_val = INT_MAX;
        int max_val = INT_MIN;
        for (int num : nums) {
            min_val = min(min_val, num);
            max_val = max(max_val, num);
        }
        for (int num : nums) {
            if (num != min_val && num != max_val) {
                return num;
            }
        }
        return -1;
    }
};

为什么两个for循环时间复杂度还是不变的

两种方法在时间复杂度上都是O(n),因为它们都需要遍历整个数组。这里的n表示数组的大小。两次遍历数组并不会改变时间复杂度的大O标记,因为O(2n)仍然等于O(n)。因此同一个数组遍历两遍,时间复杂度依然是O(n)

空间复杂度上,两种方法也都是O(1),因为它们都只使用了有限数量的变量,且这个数量与输入数组的大小无关。

但是,就实际运行时间而言,第二种方法可能会更快一些。原因有两个:

  • 没有使用erase操作,erase操作会导致数组中剩余的元素移动,从而增加额外的时间开销
  • 第二种方法在找到一个不是最小或最大的数字后就立即返回,而不是总是遍历整个数组。

所以在最好的情况下,第二种方法的时间复杂度实际上可能比O(n)更低。

6465.执行子串操作后的字典序最小字符串

  • ASCII码字符的加减可以直接’b’+1=‘c’,但是a的减法是特殊情况。‘a’-1是不可打印字符需要单独赋值
  • 这道题重点在于题意理解。子字符串并没有规定长度,但是我们需要操作一个子字符串
  • 尽量减少字典序的方式就是字符串中**'a’尽可能多**。但是,如果原本的字符串全是a,也必须进行一次操作

给你一个仅由小写英文字母组成的字符串 s 。在一步操作中,你可以完成以下行为:

  • 选则 s 的任一非空子字符串,可能是整个字符串,接着将字符串中的每一个字符替换为英文字母表中的前一个字符。例如,‘b’ 用 ‘a’ 替换,‘a’ 用 ‘z’ 替换。

返回执行上述操作 恰好一次 后可以获得的 字典序最小 的字符串。

子字符串 是字符串中的一个连续字符序列。

现有长度相同的两个字符串 x 和 字符串 y ,在满足 x[i] != y[i] 的第一个位置 i 上,如果 x[i] 在字母表中先于 y[i] 出现,则认为字符串 x 比字符串 y 字典序更小

示例 1:

输入:s = "cbabc"
输出:"baabc"
解释:我们选择从下标 0 开始、到下标 1 结束的子字符串执行操作。 
可以证明最终得到的字符串是字典序最小的。

示例 2:

输入:s = "acbbc"
输出:"abaab"
解释:我们选择从下标 1 开始、到下标 4 结束的子字符串执行操作。
可以证明最终得到的字符串是字典序最小的。

示例 3:

输入:s = "leetcode"
输出:"kddsbncd"
解释:我们选择整个字符串执行操作。
可以证明最终得到的字符串是字典序最小的。

提示:

  • 1 <= s.length <= 3 * 105
  • s 仅由小写英文字母组成

思路

这道题题意感觉不太好理解,首先选择的是子字符串,子字符串的长度并没有规定。

另外,恰好一次指的是只操作一个子字符串。并且必须操作,不能不操作原样返回

在这个问题中,一个关键的点是如果字符串中有’a’,我们应该尽可能地避免改变它前面的字符,因为’a’已经是最小的字符,不能再被减小

所以我们可以找到第一个’a’字符,并将其前面的所有字符减一。如果字符串中没有’a’,那么我们只需简单地减少整个字符串的每个字符。

最开始的写法

class Solution {
public:
    string smallestString(string s) {
        if(s.size() == 1 && s[0] == 'a'){
            return "z";
        }
        int n = s.size();
        for(int i = 0; i < n; ++i) {
            if(s[i] != 'a') {
                while(i < n && s[i] != 'a') {
                    s[i] = s[i] - 1 == 'a' - 1 ? 'z' : s[i] - 1;
                    ++i;
                }
                break;
            }
        }
        return s;
        
    }
};

这个写法存在的问题在于,当输入"aa"的时候,预期输出是"az",而不是"aa"。

题意理解的问题

输入"aa"的时候,字典序最小的字符串确实还是"aa"。但是,题目要求我们必须执行恰好一次操作,这就意味着我们必须选择字符串中的至少一个字符进行替换

在这种情况下,最好的策略就是尽可能保留字典序较小的字符,也就是只将最后一个’a’替换为’z’,得到"az"。因为’z’在字母表中的位置较后,所以"az"是在执行一次操作后能得到的字典序最小的字符串。

修改版

  • 保证每一个非’a’字符都会被减小,使得结果字符串尽可能地小。同时,遇到’a’就停止替换,保证了不会无意义地增大字符串。
class Solution {
public:
    string smallestString(string s) {
        //特殊测试用例,后来添加
        if(s.size()==1&&s[0]=='a'){
            return "z";
        }
        
        int n = s.size();
        int i = 0;
        //"a"的部分不动
        while(i < n && s[i] == 'a') {
            i++;
        }
        if(i == n) {  // 如果所有的字符都是 'a',我们还是需要进行一次操作
            s[n-1] = 'z';
        } 
        else {
            //遇到a的时候,停止替换
            while(i < n && s[i] != 'a') {
                s[i] = s[i] - 1;
                i++;
            }
        }
        return s;  
    }
};

'a’必须单独拿出来的原因

'a' - 1 在ASCII码中是不可打印字符,所以用 s[i] - 1 == 'a' - 1 是在判断 s[i] 是否是字符 ‘a’。如果是 ‘a’,将其替换为 ‘z’ (因为题目中说 ‘a’ 需要替换为 ‘z’);否则,字符 s[i] 就被替换为它的前一个字符,即 s[i] - 1

ASCII码字符的加减可以直接’b’+1=‘c’,但是a的减法是特殊情况

6449.收集巧克力

  • 注意本题的重点是,由于给出的限制条件nums长度在1000以内,所以可以考虑O(n^2)的算法

给你一个长度为 n 、下标从 0 开始的整数数组 nums ,表示收集不同巧克力的成本。每个巧克力都对应一个不同的类型,最初,位于下标 i 的巧克力就对应第 i 个类型。

在一步操作中,你可以用成本 x 执行下述行为:

  • 同时对于所有下标 0 <= i < n - 1 进行以下操作, 将下标 i 处的巧克力的类型更改为下标 (i + 1) 处的巧克力对应的类型。如果 i == n - 1 ,则该巧克力的类型将会变更为下标 0 处巧克力对应的类型。

假设你可以执行任意次操作,请返回收集所有类型巧克力所需的最小成本。

示例 1:

输入:nums = [20,1,15], x = 5
输出:13
解释:最开始,巧克力的类型分别是 [0,1,2] 。我们可以用成本 1 购买第 1 个类型的巧克力。
接着,我们用成本 5 执行一次操作,巧克力的类型变更为 [2,0,1] 。我们可以用成本 1 购买第 0 个类型的巧克力。
然后,我们用成本 5 执行一次操作,巧克力的类型变更为 [1,2,0] 。我们可以用成本 1 购买第 2 个类型的巧克力。
因此,收集所有类型的巧克力需要的总成本是 (1 + 5 + 1 + 5 + 1) = 13 。可以证明这是一种最优方案。

示例 2:

输入:nums = [1,2,3], x = 4
输出:6
解释:我们将会按最初的成本收集全部三个类型的巧克力,而不需执行任何操作。因此,收集所有类型的巧克力需要的总成本是 1 + 2 + 3 = 6

提示:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 109
  • 1 <= x <= 109

思路

思路基于一个关键的观察:在收集所有类型巧克力的过程中,我们可以通过执行一次操作来在某种程度上改变巧克力类型的顺序。这意味着,如果某种类型的巧克力的成本比较高,我们可以通过一些操作使得它被替换成其他类型的巧克力,这样就可以降低总的收集成本。

注意提示信息

本题给出的n的大小是1000以内,也就是说可以使用O(n^2)的做法

完整版

class Solution {
public:
    long long minCost(vector<int>& nums, int x) {
       long long ans = LLONG_MAX;
        int n = nums.size();
        vector<int> cost(n); // 记录每个点的最小花费
        for (int i = 0; i < n; ++i) 
            cost[i] = nums[i];  
       
        for (int d = 0; d < n; ++d) {   // 尝试移动d次
            long long cnt = 0;   // 移动d次时的最小花费
            for (int i = 0; i < n; ++i) {
                int newcost = nums[(i - d + n) % n];    // 这个点移动d次是否找到了更少的花费
                cost[i] = min(cost[i], newcost);
                cnt += cost[i];
            }
            ans = min(ans, cnt + static_cast<long long>(d) * x);
        }
        return ans;
        
    }
};

这种写法,代码中的for循环尝试了每一个可能的操作次数(从0到n-1)。对于每一种可能的操作次数d,计算了执行d次操作之后的总成本。这个成本包括每种类型巧克力的最小成本以及执行操作的成本。

然后,它找出了这些成本中的最小值,这就是收集所有类型巧克力所需的最小成本。

在计算执行d次操作之后的总成本时,对于每一个巧克力类型,都计算了执行d次操作之后的成本(通过nums[(i - d + n) % n]得到),并更新了当前类型的最小成本(通过min(cost[i], newcost)得到)。这样,cost[i]数组始终存储了对于每种类型,经过一系列操作之后的最小成本

最后要注意的一点是,这种方法的时间复杂度是O(n^2),在n较大时可能无法在合理时间内完成计算

但是本题给出的n的大小是1000以内,因此,O(n^2)这种方法是可以接受的

补充:由数据范围反推算法复杂度及算法内容

参考:由数据范围反推算法复杂度以及算法内容 - AcWing

一般ACM或者笔试题的时间限制是1秒或2秒。
在这种情况下,C++代码中的操作次数控制在 10^7∼10^8为最佳。

下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

统计学中的「标准差和方差」

标准差(Standard deviation) 简单来说&#xff0c;标准差是一组数值自平均值分散程度的一种测量观念。一个较大的标准差&#xff0c;代表大部分的数值和其平均值之间差异较大&#xff0c;一个较小的标准差&#xff0c;代表这些数值较接近平均值。 例如&#xff1a; 两组数的集…

开源数字人、虚拟直播部署教程

TheRamU/Fay: 语音互动,直播自动带货 虚拟数字人 (github.com) gitee fay: 这是一个数字人项目,包含python内核及ue数字人模型,可以用于做数字助理及自动直播,又或者作为你的应用入口也很帅 (gitee.com) 2022.10.27 补充mac上的安装办法:(34条消息) Fay数字人开源项目…

prisma 学习记录

1、prisma 可以看做是一个 ORM。 安装 prisma npm install prisma -D 设置要链接的数据库 npx prisma init --datasource-provider sqlite --datasource-provider 要使用的数据库 2、prisma 中的模型&#xff0c; 表示底层数据库中的表或者集合。 生成 Prisma Client API 的基…

chatgpt赋能python:Python中的延迟:如何暂停程序执行?

Python中的延迟&#xff1a;如何暂停程序执行&#xff1f; 如果你在编写Python程序时需要实现延迟效果&#xff0c;比如等待某些条件满足后再进行下一步操作&#xff0c;那么你可能需要使用Python提供的延迟功能。这篇文章将介绍Python中的延迟实现方法&#xff0c;并提供几个…

记一次面试中的相关问题

1. protobuf内部的实现原理 序列化与反序列化&#xff0c;比如对于数字它要求根据数字的大小选择存储空间&#xff0c;小于15的数字只用1个字节来表示&#xff0c;大于15的数用2个字节来表示&#xff0c;以此类推&#xff0c;这样要求可以尽可能地节省空间。Protobuf的一大特点…

chatgpt赋能python:Python教程:如何建立一个空列表

Python教程&#xff1a;如何建立一个空列表 Python是一种广泛应用于科学计算、数据分析、机器学习等领域的高级编程语言。在Python中&#xff0c;列表是一种非常重要的数据类型&#xff0c;可以用来存储许多不同类型的数据。在本文中&#xff0c;我们将介绍如何在Python中建立…

OJ Primed Subsequence

原题链接&#xff1a;传送锚点 1.题目 Description Given a sequence of positive integers of length n, we define a primed subsequence as a consecutive subsequence of length at least two that sums to a prime number greater than or equal to two. For ex…

【嵌入式IMAGE 3】opencv的搭建

1. OpenCV源代码下载地址 https://opencv.org/releases/ 2. 在windows平台编译&#xff08;mingw版本&#xff09; 2.1 下载cmake https://cmake.org/files/ 2.2 配置编译器环境变量 2.3 打开cmake-gui.exe a.Use default native compilers 使用默认的本机编译器 b.Specify n…

MyBatis(全)

文章目录 什么是MyBatis?MyBatis快速入门查询user表中所有数据 Mapper代理开发使用Mapper代理方式完成入门案例 MyBatis核心配置文件配置文件完成增删改查案例&#xff1a;完成品牌数据的增删改查操作准备环境查询-查询所有数据查询-查看详情查询-条件查询--1.多条件查询方法1…

css移动端

目录 谷歌模拟器 屏幕分辨率 视口 二倍图 适配方案 rem 简介 问题 媒体查询 移动端 设备宽度不同&#xff0c;HTML标签字号设置多少合适 flexible.js rem-移动端适配 less 注释 运算 嵌套 变量 导入 导出 禁止导出 谷歌模拟器 模拟移动设备&#xff0c;方…

MySQL Community Server的安装配置教程(Windows版本)

&#xff08;1&#xff09;了解MySQL Community Server&#xff1a; MySQL Community Server是开源的MySQL数据库服务的名称。它是MySQL AB在2000年推出的一个开源数据库服务器&#xff0c;现在由Oracle公司维护和管理。 MySQL Community Server是一个关系型数据库系统&#…

通讯录管理系统(cpp)

一 系统需求 主要用C来实现一个通讯录管理系统 需要包含以下功能 添加联系人&#xff1a;向通讯录中添加新人&#xff0c;信息包括姓名、性别、年龄、联系电话、家庭住址&#xff0c;最多记录1000人显示联系人&#xff1a;显示通讯录中所有联系人信息删除联系人&#xff1a;按…

【Spring】— 动态SQL :MyBatis的关联映射

目录 MyBatis的关联映射1、关联关系概述2、MyBatis中的关联关系2.1 一对一2.2 一对多2.3 多对多 MyBatis的关联映射 在实际应用中&#xff0c;对数据库的操作会涉及多张表&#xff0c;这在面向对象中就涉及对象与对象之间的关联关系。针对多表之间的操作&#xff0c;MyBatis提…

全志V3S嵌入式驱动开发(wifi驱动)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 荔枝派上面除了支持v3s自带的有线网口&#xff0c;还带有一个支持sd协议的esp 8089 wifi模块。有了这个模块&#xff0c;v3s没有网线&#xff0c;也…

chatgpt赋能python:Python程序与SEO:如何建立程序使您的网站优化更好

Python程序与SEO&#xff1a;如何建立程序使您的网站优化更好 今天&#xff0c;越来越多的网站和在线业务转向搜索引擎优化&#xff0c;以吸引更多访问者和客户。Python编程语言是一种快速、灵活、易于学习的工具&#xff0c;如果正确使用它可以使您的网站SEO更好。下面我们来…

【从删库到跑路】MySQL系列——数据库的介绍MySQL的启动

&#x1f38a;专栏【MySQL】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f354;什么是数据库⭐组成⭐数据库的优势 &#x1f35…

Spring Security--自动登录

也就是remember me 在配置链上加一个 然后发送请求时加上:remember-me字段 value值可以为&#xff0c;ture&#xff0c;1&#xff0c;on 我们记住登录后&#xff0c;关掉浏览器再打开&#xff0c;访问一下接口&#xff0c;可以访问&#xff0c;说明记住登录成功了。 因为有的…

Spring中Bean的生命 周期与作用域

文章目录 前言Bean的作用域概念Bean作用域类型1. singleton&#xff1a;单例作⽤域2. prototype&#xff1a;原型作⽤域&#xff08;多例作⽤域&#xff09;3. request&#xff1a;请求作⽤域4. session&#xff1a;回话作⽤域5. application&#xff1a;全局作⽤域6. websocke…

51单片机实训项目之“红外控制小风扇”代码详解

本代码实现的功能是通过红外遥控来控制风扇的转速。废话不多说&#xff0c;直接上代码。 另外补充一点红外通信的原理&#xff1a; 红外接收 NEC协议&#xff1a; 数据格式 发射端的方波图&#xff0c;接收端的正好与之相反&#xff0c;数据传输从最低位开始 NEC 标准下…

mqtt.fx连接阿里云物联网平台

这里写目录标题 注册公共示例创建产品添加设备创建云产品流转生成基本信息配置mqtt.fx客户端数据传送 前提条件&#xff1a;下载mqtt.fx软件&#xff0c;以及注册好阿里云物联网平台账号 本实验用两个mqtt.fx客户端接入阿里云物联网平台&#xff0c;来实现不同设备间消息的传输…