leetcode-字符串
1.反转字符串LeetCode344. 20230911
难度为0,此处就不放代码了
- 注意reverse和swap等一系列字符串函数什么时候该用,记一记库函数
- swap可以有两种实现,涨知识了,除了temp存值还可以通过位运算:s[i] ^= s[j]; s[j] ^= s[i]; s[i] ^= s[j];
2.反转字符串LeetCode541. 20230917
这一题做的时候其实有点奇怪,想了好多方法都被自己否掉,然后看题解发现for里面i+=2k才恍然大悟,又看到reverse里面用了s.begin()+i这个用法,这才明白为啥本题本来很简洁被我写得那么复杂
这个题在今天再重拾的时候觉得完全不用自己想,就按部就班地按着题意写就行了
然后看到还有一个reverse的用法是reverse(s,i,i+k),第一个而是字符串,第二个和第三个是一个左闭右开的区间
3.替换空格 剑指Offer 05. 20230917
自己做的:开了一个string,if else地一个个字符加进去了。
卡尔说的:可以先用resize函数将s先变长到最终的长度,然后用双指针法一个一个从后往前填字符。但是在写的时候犯了一个很蠢的错误,resize之后的长度已经变了,我还在用s.length()表示旧的,s.length()+ 2 *num 表示新的。下面是正确的代码。
class Solution { public:string replaceSpace(string s) {int spacenum = 0;for(char i : s){if(i == ' ') spacenum++;}int size = s.length();int left = size - 1;s.resize(s.length() + 2*spacenum); for(int right = size + 2*spacenum - 1; right > 0; right--){if(s[left] != ' '){s[right] = s[left];left--;}else{s[right] = '0';s[right - 1] = '2';s[right - 2] = '%';left--;right -= 2;}}return s;} };
4.翻转字符串里的单词 LeetCode 151. 20230919-10/03
思路还是蛮简单,就是写的时候老转不过弯。
- split函数似乎可以实现分割string里面的单词,不过C++里好像没有
2. 学习了一下erase函数(没用到):C++标准库中的
erase
函数通常用于从容器(例如std::vector
、std::string
、std::list
等)中删除元素,例如std::vector<int> myVector = {1, 2, 3, 4, 5}; // 删除第三个元素(索引为2) myVector.erase(myVector.begin() + 2);
std::string myString = "Hello, World!"; // 删除从索引6开始的5个字符 myString.erase(6, 5);
std::vector<int> myVector = {1, 2, 3, 4, 5, 6}; // 删除第二个到第四个元素 myVector.erase(myVector.begin() + 1, myVector.begin() + 4);
然而,erase背后的实现是O(N)的时间复杂度,如果外面再套一个for循环就是O(N²)的复杂度。
3. 本题写的代码,显示自己定义一个闭区间倒置函数,然后经过两次倒转就可以。里面细节非常多,什么时候+1,什么时候到末尾要判断,什么时候-1,都很凌乱
class Solution { public:void m_reverse(string &s, int a, int b){for(int i = 0; i < (b - a + 1)/2; ++i){swap(s[a + i], s[b - i]); }}string reverseWords(string s) {//去除空格int fast = 0, slow = 0;while(fast < s.length()){if(s[fast] != ' ')s[slow++] = s[fast++];else if(slow != 0){while(s[fast] ==' ' && fast < s.length()){fast++;}if(fast != s.length())s[slow++] =' ';}else{fast++;}}s.resize(slow);//全倒reverse(s.begin(),s.end());//闭区间m_reversefor(int i = 0, j = 0; i < s.length(); ++i){while(s[i] != ' ' && i < s.length())++i;m_reverse(s, j, i - 1);cout<<i<<" "<<j<<endl;cout<<s<<endl;j = i + 1;}return s;} };
5.左旋转字符串 剑指Offer 58 - II 20230917
简单的做法就是使用substr函数,注意substr的第二个参数是“多长”而不是“到哪”。
string substr1 = s.substr(0, n); s = s.substr(n, s.length() - n)+ substr1; return s;
然后还有原地旋转的思路:
先局部反转,再整体反转,很妙
reverse(s.begin(), s.begin() + n);reverse(s.begin() + n, s.end());reverse(s.begin(), s.end());
里面两个注意点:
一个是reverse()里面的两个参数:
- 首先,std::vector<int> vec = {1, 2, 3, 4, 5}; auto it = vec.begin() + 2; // it指向第三个元素,即3 std::cout << *it << std::endl; // 输出 3 因为vec.begin()指向第一个元素,也即vec.begin()+0,那么+2就是指向第三个元素
- 其次,如果是reverse(vec.begin(), vec.begin() + 2);要记住reverse的第一个参数是第一个元素,第二个参数是最后一个元素的下一个元素。也即,虽然begin()指的是1,begin()+2指的是3,但是反转的是1,2此处反转成为{2,1,3,4,5}
另一个是reverse、substr的内部实现,及它们的时间复杂度
为什么要看内部实现,因为做题的时候会想着要把时间复杂度降低,但是使用库函数有的时候就会忽略掉本身这个函数自己实现的时候用的时间复杂度,所以在这里简单看一下
reverse: 源码实现是while ((first!=last)&&(first!=--last)) { std::iter_swap (first,last); ++first; },也就是只遍历一遍即可,而swap是之前讲过的,要么是疑惑,要么是temp存,总之是用temp和数组定位。最终合起来的结果也就是遍历一遍,对每个元素O(1)的时间复杂度,最后是O(N)。
substr: 实现思路为创建一个新的字符串对象,将原始字符串中的子字符串复制到新的字符串中。复制的时间复杂度与子字符串的长度成正比,因此是 O(N)。
6.找出字符串中第一个匹配项的下标-KMP LeetCode28. 20231019
KMP居然是简单题吗,好吧
将近一个月没写。
这道题连着看了得有好几天了,但是依然不太会。今天终于约摸着把next数组和利用next数组进行匹配的代码写出来了,但是其实还是没有完全理解。
};class Solution {public:int strStr(string haystack, string needle) {//next数组int length = needle.length();int next[length];next[0] = 0;//int j = 0;// 前缀末尾// 求next数组for(int i = 1; i < length; ++i){while(j > 0 && needle[i] != needle[j]){j = next[j-1];}if(needle[i]==needle[j]){j++;}next[i] = j;}int n = 0;//用next数组去做匹配for(int m = 0; m < haystack.length(); ++m){while(n > 0 && haystack[m] != needle[n])n = next[n-1];if(haystack[m] == needle[n])n++;if(n == length)return m - length + 1;}return -1;}
aabaa前缀(不带末尾):针对a为空;针对aa为a;针对aab为a,aa;针对aaba为a,aa,aab;针对aabaa为a,aa,aab,aaba
后缀(不带头):针对a为空;针对aa为a;针对aab为b,ab;针对aaba为a,ba,aba;针对aabaa为a,aa,baa,abaa
首先是求next数组。
1)初始化的时候,next数组第一个必为0,这是因为位置0前后缀不可能相等(后缀位置0没有)。
2)然后开始从i=1挨个填next数组,在填这个数组的时候就已经用到了kmp思想了。具体表现为填next[i]的时候,j也不是一直从头开始匹配的。j先为0,如果needle串s的s[i]!=s[j],此时说明j要往前移动,但是只移到next[j-1]那边(注意点:while、>0);如果needle串的s[i]==s[j],就j++;然后,next[i]=j,进行到next[i+1]。
然后是利用next数组进行匹配。
这个地方也就是遍历haystack串,与模式串匹配就两个指针都自动后移,不匹配就模式串的指针往前移(依旧是while、>0注意),然后这个地方还有一个根据题意返回一下结果。
这个题让我自己想是完全不可能想出来的,感觉以后还得复习三遍才能记住
7. 重复的子字符串 LeetCode 459. 20231019
第一种解法的思想是两个s拼接起来如果去头去尾还含有s,那么s是可以由重复子串构成的。
理解:
[xx {xxxx][xx} xxxx] 如果{xxxxxx}=[xxxxxx],证明[xx={xx;{xx=xx];xx]=[xx};而[xx}=[xx,所以
[xx={xx=xx]=[xx},所以xx为[xxxxxx]可用来重复的子串。大概这么理解吧,不再看严格数学证明。
里面有两个亮点:erase函数删除特定位置的元素,以及string::npos代表没找到任何位置。
class Solution { public:bool repeatedSubstringPattern(string s) {//方法1.移动匹配--具体表现为拼接-删除首尾-调用find库函数string ss = s+s;ss.erase(ss.length()-1,1);ss.erase(0,1);auto it = ss.find(s);if (it != string::npos)return 1;return 0;} };
第二种解法是KMP,
class Solution { public:bool repeatedSubstringPattern(string s) {//方法2.KMP--两个思路中的关键数学证明//1. 如果是由子串重复构成,那么最长相等前后缀不包含的那个子串就是所要求的子串。//2. 如果子串整除整个串,那么整个串就是由这个子串重复构成的。这个依然看我关于[xx {xxxx][xx} xxxx] 的理解,总而言之各个部分都相等。//下面,首先是算next数组,我们需要知道next[s.length()-1]等于多少,因为这个值就代表我们整个串的相等前后缀有多长。然后,用s.length()-next[s.length()-1] 除 s.length(), 如果能整除,就返回1,否则返回0。int length = s.size();//int next[length]={0};int next[s.length()];next[0] = 0;int j = 0;for (int i = 1; i < length; ++i){while(j > 0 && s[j]!=s[i])j = next[j-1];if(s[j]== s[i])j++;next[i] = j;}if(next[length-1] != 0 && (length % (length - next[length-1]) == 0))return 1;return 0;} };
注1: next[length-1] != 0 要加,漏了完全没有相等前后缀的情形。
注2:int next[s.length()];这种用法很奇怪,按本科讲的课来说应该写成int *next = new int[s.length()];才行。
leetcode的奇怪机制:
·参数是(string s),在函数体内定义一个数组int array[s.length()];可以过
·int array[s.length()]={0};过不了
·int array[s.length()]; for (int i = 0; i < s.length(); ++i) {array[i] = 0;}又能过其他:LeetCode刷题总结-字符串篇 - 舞动的心 - 博客园 (cnblogs.com) (还有什么题可刷)待看
相关文章:

leetcode-字符串
1.反转字符串LeetCode344. 20230911 难度为0,此处就不放代码了 注意reverse和swap等一系列字符串函数什么时候该用,记一记库函数 swap可以有两种实现,涨知识了,除了temp存值还可以通过位运算:s[i] ^ s[j]; s[j] ^ s[i…...

多线程---synchronized特性+原理
文章目录 synchronized特性synchronized原理锁升级/锁膨胀锁消除锁粗化 synchronized特性 互斥 当某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象的synchronized就会阻塞等待。 进入synchronized修饰的代码块相当于加锁 退出synchronize…...

Qt实现卡牌对对碰游戏
效果 闲来无事,实现一个对对碰游戏,卡牌样式是火影动漫。 先上效果: 卡牌对对碰_火影主题 玩法 启动游戏,进入第一关卡,所有卡牌都为未翻开状态,即背面朝上;点击卡牌,则将卡牌翻开…...

【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割7(数据预处理)
在上一节:【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割6(数据预处理) 中,我们已经得到了与mhd图像同seriesUID名称的mask nrrd数据文件了,可以说是一一对应了。 并且,mask的文件,还根据结…...

极米科技H6 Pro 4K、H6 4K高亮定焦版——开启家用投影4K普及时代
智能投影产业经过几年发展,市场规模正在快速扩大。洛图数据显示,预计今年中国投影出货量有望超700万台,2027年达950万台,可见智能投影产业规模将逐渐壮大,未来可期。2023年,投影行业呈现出全新面貌…...

软考系统架构师知识点集锦九:数据库系统
一、考情分析 二、考点精讲 2.1数据库概述 2.1.1数据库模式 (1)三级模式:外模式对应视图,模式(也称为概念模式)对应数据库表,内模式对应物理文件。(2)两层映像:外模式-模式映像,模式-内模式映像;两层映像可以保证数据库中的数据具有较高的…...

IOC课程整理-6 Spring IoC 依赖注入
1 依赖注入的模式和类型 模式 类型 2 自动绑定(Autowiring) 官方定义 “自动装配是Spring框架中一种机制,用于自动解析和满足bean之间的依赖关系。通过自动装配,Spring容器可以根据类型、名称或其他属性来自动连接协作的bean&…...

FANUC机器人PRIO-621和PRIO-622设备和控制器没有运行故障处理
FANUC机器人PRIO-621和PRIO-622设备和控制器没有运行故障处理 如下图所示,新的机器人开机后提示报警: PRIO-621 设备没有运行 PRIO-622 控制器没有运行 我们首先查看下手册上的报警代码说明,如下图所示, 如下图所示,…...

《动手深度学习》线性回归简洁实现实例
🎈 作者:Linux猿 🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊! &…...

国家数据局正式揭牌,数据专业融合型人才迎来发展良机
📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于恒川的日常汇报系列,大家有兴趣的可以看一看 📘相关专栏C语言初阶、C…...

基于springboot实现休闲娱乐代理售票平台系统项目【项目源码+论文说明】
基于springboot实现休闲娱乐代理售票系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把休闲娱乐代理售票管理与现在网络相结合,利用java技术建设休闲娱乐代理售票系统,实现休闲娱乐代理售票的信息化。则对于进一步提高休闲娱乐代理售票管理发…...

3.AUTOSAR OS分析(一)
1. AUTOSAR OS诞生背景 在最初接触汽车ECU开发时,提到最多的还是OSEK,比如OSEK NM、OSEK OS等等;而OSEK/VDK操作系统也是最先引入汽车行业;OSEK OS是基于事件触发的操作系统,有以下特性: 固定优先级调度中断处理函数StartOS和StartupHook作为启动阶段的通用接口函数Shutd…...

AB试验(七)利用Python模拟A/B试验
AB试验(七)利用Python模拟A/B试验 到现在,我相信大家理论已经掌握了,轮子也造好了。但有的人是不是总感觉还差点什么?没错,还缺了实战经验。对于AB实验平台完善的公司 ,这个经验不难获得&#…...

Go语言入门-流程控制语句
流程控制 Go语言中有以下几种常见的流程控制语句: 条件语句(Conditional Statements): if语句:用于根据条件执行代码块。else语句:在if条件不满足时执行的语句块。else if语句:用于在多个条件之…...

深入探究ASEMI肖特基二极管MBR60100PT的材质
编辑-Z 在电子零件领域中,肖特基二极管MBR60100PT因其出色的性能和广泛的应用而显得尤为关键。理解其材质不仅有助于我们深入理解其运作原理,也有助于我们做出更合适的电子设计。那么,肖特基二极管MBR60100PT是什么材质呢? 首先,…...

python类模拟“对战游戏”
Game类含玩家昵称、生命值、攻击力(整数),暴击率、闪避率(小数),在魔术方法init定义;attack方法中实现两个Game实例对战模拟。 (本笔记适合初通Python类class的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.py…...

Maven第二章:Maven基本概念与生命周期
Maven第二章:Maven基本概念与生命周期 前言 本章主要内容,介绍Maven基本概念,包括maven坐标含义,命名规则,继承与聚合、了解与理解生命周期,如何通过Maven进行依赖和版本管理。 什么是Maven的坐标…...

<蓝桥杯软件赛>零基础备赛20周--第3周--填空题
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周(读者可以按…...

【Linux】VM及WindowsServer安装
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《微信小程序开发实战》。🎯Ἲ…...

【实用教程】MySQL内置函数
1 背景 在MySQL查询等操作过程中,我们需要根据实际情况,使用其提供的内置函数。今天我们就来一起来学习下这些函数,在之后的使用过程中更加得心应手。 2 MySQL函数 2.1 字符串函数 常用的函数如下: concat(s1,s2,…sn)字符串…...

第十二节——ref
一、概念 ref 被用来给DOM元素或子组件注册引用信息。引用信息会根据父组件的 $refs 对象进行注册。如果在普通的DOM元素上使用,引用信息就是元素; 如果用在子组件上,引用信息就是组件实例。 注意:只要想要在Vue中直接操作DOM元素ÿ…...

少儿编程 2023年9月中国电子学会图形化编程等级考试Scratch编程四级真题解析(判断题)
2023年9月scratch编程等级考试四级真题 判断题(共10题,每题2分,共20分) 11、运行程序后,变量"result"的值是6 答案:对 考点分析:考查积木综合使用,重点考查自定义积木的使用 图中自定义积木实现的功能是获取两个数中最大的那个数并存放在result变量中,左…...

【设计模式三原则】
设计模式三原则 单一职责原则开放封闭原则依赖倒转原则里氏代换原则 我们在进行程序设计的时候,要尽可能地保证程序的可扩展性、可维护性和可读性,所以需要使用一些设计模式,这些设计模式都遵循了以下三个原则,下面来依次为大家介…...

600MW发电机组继电保护自动装置的整定计算及仿真
摘要 随着科技的发展,电力已成为最重要的资源之一,如何保证电力的供应对于国民经济发展和人民生活水平的提高都有非常重要的意义。在电能输送过程中,发电机组是整个过程中最重要的一个基本元素,在电力系统中的输送和分配中被广泛应…...

【蓝桥每日一题]-字符串(保姆级教程 篇1)#atcoder324C~E题
今天来讲字符串题型 目录 题目:atcoder324C题 思路: 题目:atcoder324D题 思路: 题目:atcoder324E题 思路: 题目:atcoder324C题 给一个T字符串,然后给出n个S串,对…...

4.2.1 SQL语句、索引、视图、存储过程
怎么执行一条select语句 1.连接器 接收连接-》管理连接-》校验用户信息 2.查询缓存 kv存储,命中直接返回,否则继续执行 8.0已经删除 3.分析器 词法句法分析生成语法树 4.优化器 指定执行计划,选择查询成本最小的计划 5.执行器 根据执行计划&a…...

1992-2021年全国各地级市经过矫正的夜间灯光数据(GNLD、VIIRS)
1992-2021年全国各地级市经过矫正的夜间灯光数据(GNLD、VIIRS) 1、时间:1992-2021年3月,其中1992-2013年为年度数据,2013-2021年3月为月度数据 2、来源:DMSP、VIIRS 3、范围:分区域汇总&…...

机器人的触发条件有什么区别,如何巧妙的使用
简介 维格机器人触发条件,分为3个,分别是: 有新表单提交时、有记录满足条件时、有新的记录创建时 。 看似3个,其实是能够满足我们非常多的使用场景。 本篇将先介绍3个条件的触发条件,然后再列举一些复杂的触发条件如何用现有的触发条件来满足 注意: 维格机器人所有的…...

【Qt6】QStringList
2023年10月31日,周二上午 QStringList 是 Qt 中的一个类,用于存储一组字符串。它提供了一些方便的方法来操作和管理字符串列表。 QStringList 可以用于存储任意数量的字符串,并提供了一些常用的操作,例如添加、删除、查找、排序等…...

代码随想录算法训练营第五十三天|309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费
309. 买卖股票的最佳时机含冷冻期 int maxProfit(int* prices, int pricesSize){int len pricesSize;int dp[len][4];dp[0][0] -prices[0];dp[0][1] 0;dp[0][2] 0;dp[0][3] 0;for (int i 1; i < pricesSize; i){dp[i][0] fmax(dp[i-1][0], fmax(dp[i-1][1] - prices…...