LeetCode --- 420周赛

news2024/10/27 20:46:47

题目列表

3324. 出现在屏幕上的字符串序列

3325. 字符至少出现 K 次的子字符串 I

3326. 使数组非递减的最少除法操作次数

3327. 判断 DFS 字符串是否是回文串


一、出现在屏幕上的字符串序列

根据题目意思进行模拟即可,代码如下

class Solution {
public:
    vector<string> stringSequence(string target) {
        vector<string> ans;
        int n = target.size();
        string tmp;
        for(int i = 0; i < n; i++){
            tmp += 'a';
            ans.push_back(tmp);
            while(target[i]!=tmp[i]){
                tmp[i] = (tmp[i] - 'a' + 1)%26 + 'a';
                ans.push_back(tmp);
            }
        }
        return ans;
    }
};

二、字符至少出现 K 次的子字符串I

题目要求我们统计符合条件的子字符串的个数,类似这种维护区间某种性质的题,都可以考虑用滑动窗口来做,这题也是同理。滑动窗口维护的区间是以 R 为右端点,且没有一个字母出现 >= k 次的最长子字符串。那么以 R 为右端点的符合题目要求的子字符串的个数就为 L 个,将结果相加,就能得到答案,代码如下

class Solution {
public:
    int numberOfSubstrings(string s, int k) {
        int n = s.size(), ans = 0;
        int cnt[26]{};
        for(int l = 0, r = 0; r < n; r++){
            ++cnt[s[r] - 'a'];
            // [l, r] 内不存在字符的个数 >= k
            while(cnt[s[r] - 'a'] == k){
                --cnt[s[l] - 'a'];
                l++;
            }
            ans += l; // 左端点在[0, l)内的都满足题目要求
        }
        return ans;
    }
};

三、使数组非递减的最少出发操作次数

根据题目所给的描述,我们能得到以下几点:

1、要求最少操作次数,根据贪心的思想,我们肯定是让后面的数字尽可能大,而我们只能让数变小,所以最后一个数不用进行操作,同时从后向前遍历数组,让遍历到的数字都保持尽量大。

2、对于任意一个数,我们最多只能执行一次操作,为什么?假设有一个数字为 x,x 的最大真因子为a,b = a/x,如果 b 还能被分解为 c * d,那么 x 的最大真因子应该是 a * c 或者 a * d,所以每个数最多只能被操作一次,且操作完的数为质数,因为无法被再次分解。

根据上述两点,我们只要提前预处理得到任意一个数能被分解为哪个质数,就能在O(1)的时间内完成对任意一个数的操作,然后倒序遍历数组就能得到答案,代码如下

const int MX = 1e6 + 1;
vector<int> f(MX);
int init = [](){
    // 时间复杂度为O(UlogU) U = MX
    for(int i = 2; i < MX; i++){
        // 没有被赋值,说明当前的数字无法被比它小的数字组成,即它是个质数
        if(f[i] == 0){ 
            for(int j = 2 * i; j < MX; j += i){
                if(f[j] == 0) // 表示之前没被赋值过,比如 51 = 3 * 17,既能被 3 赋值,又能被17 赋值,显然 f[51] = 3
                    f[j] = i;
            }
        }
    }
    return 0;
}();
class Solution {
public:
    int minOperations(vector<int>& nums) {
        int n = nums.size(), ans = 0;
        for(int i = n - 2; i >= 0; i--){
            if(nums[i] <= nums[i+1]) continue;
            if(f[nums[i]] == 0) return -1;
            nums[i] = f[nums[i]];
            if(nums[i] > nums[i+1]) return -1;
            ans++;
        }
        return ans;
    }
};

四、判断DFS字符串是否是回文字符串

题意概括如下:对每一个结点进行后序遍历得到一个字符串,并判断得到的字符串是否是回文串。这里首先要明确一点,任意结点经过后续遍历得到的字符串,都是根节点进行后序遍历得到的字符串的子串(由递归的性质决定),也就是说我们只要对根节点进行遍历得到字符串s,同时记录每个结点的字符串的区间,那么问题就变成了如何快速判断一个区间是否是回文串。

如何快速判断一个区间是否是回文串呢?这里就要介绍 Manacher 算法,用O(n)的时间进行预处理,然后用O(1)的时间判断子串是否是回文串。

代码实现如下 

class Solution {
public:
    vector<bool> findAnswer(vector<int>& parent, string s) {
        int n = parent.size();
        vector<vector<int>> g(n);
        for(int i = 1; i < n; i++)
            g[parent[i]].push_back(i);
        string t;
        // [L[i], R[i]] 表示以i为根节点进行dfs,得到的子串区间
        vector<int> R(n), L(n);
        auto dfs = [&](auto && dfs, int x)->void{
            L[x] = t.size();
            for(int y:g[x])
                dfs(dfs, y);
            R[x] = t.size();
            t += s[x];
        };
        dfs(dfs, 0);
        // 为了简化代码逻辑,不分回文串的奇偶讨论,我们在 t 的字符之间都添加一个 #
        // 同时为了不对边界情况进行特判,我们在 t 前后加上两个不同的特殊字符
        // 如 acbaddb =>  ^#a#c#b#a#d#d#b#$
        string tmp = "^";
        for(auto e : t){
            tmp += '#';
            tmp += e;
        }
        tmp += "#$";
        // Manacher 算法
        int m = tmp.size();
        vector<int> halfLen(m-2);
        int box_mid = 0, box_R = 0;
        for(int i = 2; i < m-2; i++){ // 我们并不关心以前两个字符或者最后两个字符为中点的回文串
            int hl = 1;
            // 算法的核心:根据已知条件,得到一些结论
            if(i < box_R){
                hl = min(halfLen[2 * box_mid - i], box_R - i);
            }
            while(tmp[i - hl] == tmp[i + hl]){
                hl++;
                box_mid = i, box_R = hl + i;
            }
            halfLen[i] = hl;
        }

        vector<bool> ans(n);
        for(int i = 0; i < n; i++){
            // 将 t 的区间 [L[i], R[i]] 映射到 tmp 的区间 [left, right]上
            // 下标间的关系为 2*(i+1)
            int left = 2 * (L[i] + 1), right = 2 * (R[i] + 1);
            int mid = (left + right)/2;
            ans[i] = (halfLen[mid] >= R[i] - L[i] + 1);
        }
        return ans;
    }
};

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

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

相关文章

ASP.NET Core8.0学习笔记(二十三)——EF Core自引用

一、什么是自引用 1.在常见的树状目录中&#xff0c;其结构如下&#xff1a; 每一个菜单可能有父级菜单&#xff0c;也可能有子菜单。但是无论是哪一级菜单&#xff0c;他们都是同属于菜单对象。将这个菜单对象使用代码进行描述&#xff1a; 在上面的代码中&#xff0c;主…

【论文精读】LTGC: Long-tail Recognition via Leveraging LLMs-driven Generated Content

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;论文精读_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 摘要 2. …

系统聚类比较——最短距离法、最长距离法、重心法和类平均法

系统聚类概述 系统聚类&#xff0c;又称分层聚类法&#xff0c;是一种用于分析数据的统计方法&#xff0c;在生物学、分类学、社会网络等领域有广泛应用。以下是对系统聚类的详细概述&#xff1a; 一、基本思想 系统聚类的基本思想是将每个样品&#xff08;或数据点&#xf…

深入理解C++模板编程:从基础到进阶

引言 在C编程中&#xff0c;模板是实现泛型编程的关键工具。模板使得代码能够适用于不同的数据类型&#xff0c;极大地提升了代码复用性、灵活性和可维护性。本文将深入探讨模板编程的基础知识&#xff0c;包括函数模板和类模板的定义、使用、以及它们的实例化和匹配规则。 一…

《分布式机器学习模式》:解锁分布式ML的实战宝典

在大数据和人工智能时代&#xff0c;机器学习已经成为推动技术进步的重要引擎。然而&#xff0c;随着数据量的爆炸性增长和模型复杂度的提升&#xff0c;单机环境下的机器学习已经难以满足实际需求。因此&#xff0c;将机器学习应用迁移到分布式系统上&#xff0c;成为了一个不…

世界酒中国菜与另可数字平台达成战略合作

世界酒中国菜与另可数字平台达成战略合作&#xff0c;共推行业发展新高度 近日&#xff0c;在行业内引起广泛关注的“世界酒中国菜”项目&#xff0c;与“另可”数字平台成功举行了战略合作签约仪式。这一重要合作不仅是双方发展历程中的重要里程碑&#xff0c;更是继世界酒中…

如何通过视频建立3d模型

通过视频建立3D模型通常包括几个关键步骤&#xff1a;从视频中提取帧、对帧中的物体进行特征提取、将多帧中的信息结合起来恢复三维结构。Python中有一些库和工具可以帮助实现这个过程&#xff0c;例如OpenCV、Open3D、COLMAP等。以下是一个简化的流程和代码框架&#xff1a; 步…

量子计算突破:下一个科技革命的风口浪尖在哪里?

内容概要 在当今科技飞速发展的时代&#xff0c;量子计算如同一颗璀璨的明珠&#xff0c;正闪烁着无尽的可能性。它不仅是解决科学难题的钥匙&#xff0c;更是即将引领科技革命的先锋。如今&#xff0c;随着技术的不断突破&#xff0c;量子计算已经步入了一个崭新的阶段。想象…

使用React构建现代Web应用

&#x1f496; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4bb; Gitee主页&#xff1a;瑕疵的gitee主页 &#x1f680; 文章专栏&#xff1a;《热点资讯》 使用React构建现代Web应用 1 引言 2 React简介 3 安装React 4 创建React项目 5 设计应用结构 6 创建组件 7 使用组件…

Docker本地安装Minio对象存储

Docker本地安装Minio对象存储 1. 什么是 MinIO&#xff1f; MinIO 是一个开源的对象存储服务器。这意味着它允许你在互联网上存储大量数据&#xff0c;比如文件、图片、视频等&#xff0c;而不需要依赖传统的文件系统。MinIO 的特点在于它非常灵活、易于使用&#xff0c;同时…

【ruoyi-vue】ruoyi-vue 去掉数据库和redis

场景&#xff1a;采用ruoyi-vue作为一个简单的后台框架&#xff0c;不需要使用数据库&#xff0c;redis。因此采取以下方法去掉相关配置&#xff0c;防止启动时造成数据和redis不存在的报错。 1、去掉数据库 注释掉framework下的DruidConfig.java 2、去掉部分数据启动时的初…

将公有云变成本地磁盘的几种方式

因为微信更改了推送机制&#xff0c;不按照号主发文时间排序了。现在的规则是综合多种因素&#xff0c;你可能在今天收到昨天的推送&#xff0c;甚至前天的&#xff01; 如果你认可菜鸟小白的学习分享的话&#xff0c;就星标一下吧&#xff0c;只需要两步&#xff01; 这样你可…

猫头虎 分享:Python库 Click 的简介、安装、用法详解入门教程

&#x1f42f; 猫头虎 分享&#xff1a;Python库 Click 的简介、安装、用法详解入门教程 今天猫头虎带您一起探索 Click 库&#xff01;最近有位粉丝私信猫哥&#xff0c;问到在项目中如何用 Python 简单又高效地实现命令行工具。大家熟悉的 argparse 虽然功能齐全&#xff0c…

深入理解gPTP时间同步过程

泛化精确时间协议(gPTP)是一个用于实现精确时间同步的协议,特别适用于分布式系统中需要高度协调的操作,比如汽车电子、工业自动化等。 gPTP通过同步主节点(Time Master)和从节点(Time Slave)的时钟,实现全局一致的时间参考。 以下是gPTP实现主从时间同步的详细过程:…

WaveNet模型实现电力预测

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【EfficientNet-B6模型实现ISIC皮肤镜图像数据集分类】 2.【卫星图像道路检测De…

GeoWebCache1.26调用ArcGIS切片

常用网址&#xff1a; GeoServer GeoWebCache (osgeo.org) GeoServer 用户手册 — GeoServer 2.20.x 用户手册 一、版本需要适配&#xff1a;Geoserver与GeoWebCache、jdk等的版本适配对照 ​ 查看来源 二、准备工作 1、数据&#xff1a;Arcgis标准的切片&#xff0c;通过…

安全芯片 OPTIGA TRUST M 使用介绍与示例(基于STM32裸机)

文章目录 目的资料索引硬件电路软件框架介绍数据存储框架移植框架使用 使用示例示例地址与硬件连接通讯测试功能测试 总结 目的 OPTIGA TRUST M 是英飞凌推出的安全芯片&#xff0c;芯片通提供了很多 slot &#xff0c;用于存放各类安全证书、密钥、用户数据等&#xff0c;内置…

飞书文档解除复制限制

解除飞书文档没有编辑器权限限制复制功能方法 方法一&#xff1a;使用插件 方法二&#xff1a; 通过调试工具删除所有的copy事件 使用插件 缺点&#xff1a; 只有markdown格式&#xff0c;如果需要其他格式需要再通过Typora等markdown编辑器转pdf,word等格式 安装插件 Cloud Do…

Day02回文数

给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#xff0c;而 …

关于 Linux 内核“合规要求”与俄罗斯制裁的一些澄清

原文&#xff1a;Michael Larabel - 2024.10.24 当 一些俄罗斯的 Linux 开发者被从内核的 MAINTAINERS 文件中移除 时&#xff0c;原因被描述为“合规要求”&#xff0c;但并未明确这些要求具体涉及什么内容。随后&#xff0c;Linus Torvalds 对此发表了评论&#xff0c;明确指…