LeetCode---389周赛

news2024/12/28 1:48:29

题目列表

3083. 字符串及其反转中是否存在同一子字符串

3084. 统计以给定字符开头和结尾的子字符串总数

3085. 成为 K 特殊字符串需要删除的最少字符数

3086. 拾起 K 个 1 需要的最少行动次数

一、字符串及其反转中是否存在同一子字符串

 直接暴力枚举即可,代码如下

class Solution {
public:
    bool isSubstringPresent(string s) {
        bool vis[26][26]={0};// vis[x][y] 表示(s[i-1],s[i])是否出现过
        for(int i=1;i<s.size();i++){
            int x = s[i-1]-'a',y = s[i]-'a';
            vis[x][y]=true;
            if(vis[y][x])
                return true;
        }
        return false;
    }
};

// 用位运算优化
class Solution {
public:
    bool isSubstringPresent(string s) {
        int vis[26]={0};
        for(int i=1;i<s.size();i++){
            int x = s[i-1]-'a',y = s[i]-'a';
            vis[x]|=(1<<y);
            if(vis[y]>>x & 1)
                return true;
        }
        return false;
    }
};

二、统计以给定字符开头和结尾的子字符串的总数

这题就是纯数学题,就是要求我们找出特定字符的个数,然后从中选出两个组成子字符串,这题单一字符也符合条件,所以答案为n*(n-1)/2+n,n表示字符串中特定字符的出现次数

代码如下

class Solution {
public:
    long long countSubstrings(string s, char c) {
        long long n = count(s.begin(),s.end(),c);
        return n*(n-1)/2+n;
    }
};

三、成为K特殊字符串需要删除的最少字符数

仔细读完题目,你会发现这题其实和字符没多大关系,关键是频率,思路如下:

首先我们用freq[26]统计各个字符出现的次数(即频率),然后对freq进行排序,一共就26个字母的频率,我们可以暴力枚举以freq[i]为左端点,freq[i]+k为右端点的频率区间,在该区间内的字符不需要被修改,出现次数在该区间左边的字符要全被删除,出现次数在该区间右边的字符要被减少到freq[i]+k,枚举26次就能得到答案。

如何快速找到freq[i]+k对应的freq数组下标?用二分

如何快速得到前i个字符的出现次数?用前缀和

当然这题的freq数组不是很大,也就26个数,我们也可以直接遍历数组,不用二分+前缀和

代码如下

class Solution {
public:
    int minimumDeletions(string word, int k) {
        //统计频率
        int freq[26]={0};
        for(const auto&e:word)
            freq[e-'a']++;
        sort(freq,freq+26);
        int pre[27]={0};
        for(int i=0;i<26;i++) pre[i+1]=pre[i]+freq[i];
        int ans = INT_MAX;
        for(int i=0;i<26;i++){
            if(freq[i]==0) continue;
            int target=freq[i]+k;
            int l=i,r=25;
            while(l<=r){
                int m=l+(r-l)/2;
                if(freq[m]>target) r=m-1;
                else l=m+1;
            }
            ans=min(ans,pre[i]+pre[26]-pre[l]-target*(26-l));
        }
        return ans;
    }
};


class Solution {
public:
    int minimumDeletions(string word, int k) {
        int freq[26]={0};
        for(const auto&e:word)
            freq[e-'a']++;
        sort(freq,freq+26);
        int ans = 0;
        for(int i=0;i<26;i++){
            if(freq[i]==0) continue;
            int res = 0;
            for(int j=i;j<26;j++)
                res += min(freq[j],freq[i]+k);
            ans=max(ans,res);// 求能保持不变的最大字符数量
        }
        return word.size()-ans;
    }
};

四、拾起K个1需要的最少的行动次数

设 i 为Alice的站立位置的下标,j 为 1 所在位置下标

根据贪心,我们可以归纳出以下几个步骤(按照优先级排序):

a、拿 i 左右两边的1(如果 i 左右是1的话)--- 只需行动 | i - j | = 1次

b、执行操作1将maxChanges个1放在 i 的左边/右边,再执行操作2,拿到1 --- 只需行动2次

c、执行操作2将被 i 附近的1拿到 --- 需要行动 | i - j | >= 2

(如果 i 本身就是1,那么不需要操作就直接拿到一个1,该行动在代码中与步骤a和并了,可以暂不考虑)

如果需要拿出的K个1可以在前两个步骤之内完成,可以直接计算出答案(具体看代码)

否则,我们在前两步得到的x个1的基础上,再得到 K - x 个1即可,很多人都会有这样的思维惯性,但是这样是不正确的,因为步骤a和步骤c是密切相关的,我们在得到x个1时,就已经确定了Alice的位置,但是这个位置不一定是最优的,因为它还会影响步骤c,所以我们应该把步骤a和步骤c放在一起考虑,步骤b的操作次数单独计算。

如何计算步骤a和步骤c得到的 K - maxChanges 个1需要的最少操作次数?

其实观察它们的表达是| i - j | 我们就能知道,我们要求的是  K - maxChanges 个1 到达某个位置的最短的距离和,用中位数贪心【中位数贪心的证明如下】

代码如下

class Solution {
public:
    long long minimumMoves(vector<int>& nums, int k, int maxChanges) {
        int n = nums.size();
        vector<int>pos;
        // 求连续1的个数
        int mx = 0;
        for(int i = 0; i < n; i++){
            if(nums[i]==0) continue;
            pos.push_back(i);//记录1出现的位置
            int j=i++;
            while(i<n&&nums[i]){
                pos.push_back(i);//记录1出现的位置
                i++;
            }
            mx=max(mx,i-j);
        }
        
        mx = min(3,min(k,mx));
        if(mx+maxChanges>=k)
            return max(mx-1,0)+(k-mx)*2LL;// 只用步骤a/步骤a+步骤b的操作次数

        int size = k - maxChanges; // 步骤a+步骤c需要的1的个数
        int m = pos.size();
        
        long long pre[m+1]; pre[0] = 0;
        for(int i = 0; i < m; i++) pre[i+1] = pre[i] + pos[i];

        long long ans = LLONG_MAX;
        for(int i = 0; i + size-1 < m; i++){
            int l = i, r = i + size - 1;
            int m = l + (r-l)/2;// pos[m]是中位数
            long long left = 1LL*(m-l)*pos[m]-(pre[m]-pre[l]);
            long long right = pre[r+1]-pre[m+1]-1LL*(r-m)*pos[m];
            ans = min(ans, left+right);
        }
        return ans+2LL*maxChanges;
    }
};

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

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

相关文章

Linux(Centos)安装mysql 8 并且使用systemctl管理服务

1.下载mysql包 地址 MySQL :: Download MySQL Community Server (Archived Versions) 注&#xff1a;下载我圈住的减压之后里面会有tar.gz 再次减压才会是软件主体 2.安装和准备 yum -y install numactl 安装numactl tar -xvf mysql-8.0.30-el7-x86_64.tar 拆分 …

算法思想总结:位运算

创作不易&#xff0c;感谢三连支持&#xff01;&#xff01; 一、常见的位运算总结 标题 二、位1的个数 . - 力扣&#xff08;LeetCode&#xff09; 利用第七条特性&#xff1a;n&&#xff08;n-1&#xff09;干掉最后一个1&#xff0c;然后每次都用count去统计&#xff…

目标检测——PP-YOLOv2算法解读

PP-YOLO系列&#xff0c;均是基于百度自研PaddlePaddle深度学习框架发布的算法&#xff0c;2020年基于YOLOv3改进发布PP-YOLO&#xff0c;2021年发布PP-YOLOv2和移动端检测算法PP-PicoDet&#xff0c;2022年发布PP-YOLOE和PP-YOLOE-R。由于均是一个系列&#xff0c;所以放一起解…

【算法与数据结构】 C语言实现单链表队列详解

文章目录 &#x1f4dd;队列&#x1f320; 数据结构设计&#x1f309;初始化队列函数 &#x1f320;销毁队列函数&#x1f309;入队函数 &#x1f320;出队函数&#x1f309;获取队首元素函数 &#x1f320;获取队尾元素函数&#x1f309; 判断队列是否为空函数&#x1f309;获…

学习ReentrantLock 原理

ReentrantLock 与 synchronized 锁的实现&#xff1a;synchronized 是 JVM 实现的&#xff0c;而 ReentrantLock 是 JDK 实现性能&#xff1a;新版本 Java 对 synchronized 进行了很多优化&#xff0c;synchronized 与 ReentrantLock 大致相同使用&#xff1a;ReentrantLock 需…

tauri应用实现一键快速更新版本

tauri应用实现一键快速更新版本 创建一个项目 pnpm create tauri-app根据配置选择就可以 pnpm tauri dev启动项目 ##更新配置 打包配置在src-tauri/tauri.conf.json 修改打包命令 "bundle": {"active": true,"targets": "all",&qu…

石子合并与果子合并:区间动态规划和贪心

果子合并是如何将一堆果子合并起来所消耗体力最少&#xff0c;石子合并也是将一堆石子合并起来质量最小&#xff0c;但不同的是 石子合并只能相邻的两个合并 。本篇通过讲解这两个相似例题&#xff0c;来学习区间dp与贪心。 目录 石子合并&#xff1a; 题目&#xff1a; 思路…

Dr4g0n

信息收集 # nmap -sn 192.168.56.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-03-04 08:52 CST Nmap scan report for 192.168.56.2 Host is up (0.00012s latency). MAC Address: 00:50:56:FE:B1:6F (VMware) Nmap scan report …

【Redis】Redisson实现分布式锁

Redisson是一个在Redis的基础上实现的Java驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;。它不仅提供了一系列的分布式的Java常用对象&#xff0c;还提供了许多分布式服务&#xff0c;其中就包含了各种分布式锁的实现。 官网地址 GitHub地址 Redisson入门 1.引…

docker安装ES7.1.1(单机版)+ik分词器+es-head可视化

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Elasticsearch 是一…

海外媒体发稿:7款爆款标题生成器解析-华媒舍

科普文章是将科学知识普及给大众的一种方式&#xff0c;而一个引人入胜的标题往往是吸引读者的第一步。在科普领域中&#xff0c;标题的吸引力至关重要。以下将介绍7款风靡科普界的爆款标题生成器&#xff0c;帮助你创作出引人入胜的科普文章。 1. 情感引爆 情感是人类行为中的…

卷积篇 | YOLOv8改进之主干网络中引入可变形卷积DConv

前言:Hello大家好,我是小哥谈。可变形卷积模块是一种改进的卷积操作,它可以更好地适应物体的形状和尺寸,提高模型的鲁棒性。可变形卷积模块的实现方式是在标准卷积操作中增加一个偏移量offset,使卷积核能够在训练过程中扩展到更大的范围,从而实现对尺度、长宽比和旋转等各…

QML 布局管理器之GridLayout 项目demo

一.气体控制效果图 二.界面布局代码实现 //DottedLline.qml 虚线绘制 import QtQuick 2.12 import QtQuick.Shapes 1.12Shape {id:canvaswidth: parent.widthheight: parent.heightShapePath{strokeStyle: ShapePath.DashLinestartX: 8startY: 10dashPattern: [1, 3]PathLine{…

多线程和线程同步

文章目录 进程和线程线程的操作线程创建线程退出线程回收线程分离线程取消和ID比较 线程同步互斥锁死锁读写锁条件变量信号量 进程和线程 线程是轻量级的进程&#xff0c;在Linux环境下线程的本质还是进程。 在计算机上运行的程序是一组指令及指令参数的组合&#xff0c;指令按…

Web前端-JS

JavaScript&#xff0c;简称js&#xff1a;负责网页的行为&#xff08;交互效果&#xff09;。是一门跨平台&#xff0c;面向对象的脚本语言&#xff08;编写出来的语言不需要编译&#xff0c;通过浏览器的解释就可以运行&#xff09; JS引入方式 1.内嵌样式 这样打开页面就会…

毕业答辩PPT模板涵盖多种风格,包括母版的设计及主题色的设计

毕业答辩PPT模板涵盖多种风格&#xff0c;包括母版的设计及主题色的设计 前言一两个页面的展示研究内容主题概述主题内容一&#xff1a;主要面向三点研究内容主题内容二&#xff1a;主要面向两点研究内容主题内容三&#xff1a;主要面向包含应用开发的研究 前言 之前做了有关开…

Oracle Data Guard部署

Oracle的主备DG搭建 1. 修改主机名,同步时间 主库IP&#xff1a;192.168.100.137 备库IP&#xff1a;192.168.100.138配置主机名(主库) Hostname zygjpdb vim /etc/hosts 192.168.100.137 zygjpdb 192.168.100.138 zygjsdbvim /etc/sysconfig/network HOSTNAMEzygjpdb ------…

电脑如何关闭自启动应用?cmd一招解决问题

很多小伙伴说电脑刚开机就卡的和定格动画似的&#xff0c;cmd一招解决问题&#xff1a; CtrlR打开cmd,输入&#xff1a;msconfig 进入到这个界面&#xff1a; 点击启动&#xff1a; 打开任务管理器&#xff0c;禁用不要的自启动应用就ok了

机器学习算法那些事 | 使用Transformer模型进行时间序列预测实战

本文来源公众号“机器学习算法那些事”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;使用Transformer模型进行时间序列预测实战 时间序列预测是一个经久不衰的主题&#xff0c;受自然语言处理领域的成功启发&#xff0c;transfo…

C语言分支和循环

目录 一.分支 一.if 二.if else 三.if else嵌套 四.else if 五.switch语句 二.循环 一.while (do while&#xff09;break : 二.for函数&#xff1a; 三.goto语句: 四.猜数字: 一.分支 一.if if要条件为真才执行为假不执行而且if只能执行后面第一条如果要执行多条就…