leetcode-字符串

1.反转字符串LeetCode344. 20230911

难度为0,此处就不放代码了

  1. 注意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

    思路还是蛮简单,就是写的时候老转不过弯。

    1. split函数似乎可以实现分割string里面的单词,不过C++里好像没有

    2. 学习了一下erase函数(没用到):C++标准库中的erase函数通常用于从容器(例如std::vectorstd::stringstd::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) (还有什么题可刷)待看

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【c++|opencv】二、灰度变换和空间滤波---1.灰度变换、对数变换、伽马变换

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 灰度变换、对数变换、伽马变换 1. 灰度变换 #include <iostream> #include <opencv2/opencv.hpp>using namespace std; using namespace c…

03_Flutter自定义下拉菜单

03_Flutter自定义下拉菜单 在Flutter的内置api中&#xff0c;可以使用showMenu实现类似下拉菜单的效果&#xff0c;或者使用PopupMenuButton组件&#xff0c;PopupMenuButton内部也是使用了showMenu这个api&#xff0c;但是使用showMenu时&#xff0c;下拉面板的显示已经被约定…

Redis(10)| I/O多路复用(mutiplexing)

上文select/epoll 在上文《Redis&#xff08;09&#xff09;| Reactor模式》 思考问题可以使用I/O多路复用技术解决多多客户端TCP连接问题&#xff0c;同时也提到为了解决最早期的UNIX系统select调用存在的四个问题。 select(int nfds, fd_set *r, fd_set *w, fd_set *e, stru…

动手学深度学习——第七次学

LeNet&#xff08;LeNet-5&#xff09;由两个部分组成&#xff1a; 卷积编码器和全连接层密集块 卷积把高宽不断变小&#xff0c;把通道数逐渐增多&#xff0c;&#xff08;最后高宽会变成&#xff0c;通道会变得很大&#xff0c;然后做全连接进行输出&#xff09;通道信息可以…

7+共病思路。WGCNA+多机器学习+实验简单验证,易操作

今天给同学们分享一篇共病WGCNA多机器学习实验的生信文章“Shared diagnostic genes and potential mechanism between PCOS and recurrent implantation failure revealed by integrated transcriptomic analysis and machine learning”&#xff0c;这篇文章于2023年5月16日发…

人到中年应该怎么交朋友

听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…

虚拟机克隆

linux系统的组成&#xff1b; 主根目录和根目录; 所有的根目录都包含在主根目录中&#xff1b; 根目录&#xff1a; /root /home/xxx,yyy,zzz;主根目录&#xff1b;/ 一个重要的子目录&#xff1a;etc passwd, 保存了所有的三类用户信息&#xff1b;bashrc, 可以设置别名 及…

HarmonyOS开发:基于http开源一个网络请求库

前言 网络封装的目的&#xff0c;在于简洁&#xff0c;使用起来更加的方便&#xff0c;也易于我们进行相关动作的设置&#xff0c;如果&#xff0c;我们不封装&#xff0c;那么每次请求&#xff0c;就会重复大量的代码逻辑&#xff0c;如下代码&#xff0c;是官方给出的案例&am…

阿里云推出通义千问App,提供全方位的协助

&#x1f989; AI新闻 &#x1f680; 阿里云推出通义千问App&#xff0c;提供全方位的协助 摘要&#xff1a;阿里云旗下大模型通义千问App登陆各大安卓应用市场&#xff0c;具有超大规模预训练模型&#xff0c;可在创意文案、办公助理、学习助手、趣味生活等方面协助用户。功…

Transformer.js简明教程【Web AI】

Transformers.js 可在你的 Web 浏览器中实现最先进的机器学习&#xff0c;无需服务器。 它提供预训练模型和熟悉的 API&#xff0c;支持自然语言处理、计算机视觉、音频和多模态领域的任务。 借助 Transformers.js&#xff0c;开发人员可以直接在浏览器中运行文本分类、图像分类…

RPC与HTTP的关系

首选理清楚关系 RPC与HTTP是两个不同维度的东西 HTTP 协议&#xff08;Hyper Text Transfer Protocol&#xff09;&#xff0c;又叫做超文本传输协议&#xff0c;是一种传输协议&#xff0c;平时通过浏览器浏览网页网页&#xff0c;用到的就是 HTTP 协议。 而 RPC&#xff0…

Flutter FittedBox

&#x1f525; 英文单词FittedBox &#x1f525; Fitted 通过有道翻译如下 &#xff1a; Box 通过有道翻译如下 &#xff1a; 对 FittedBox 的理解 我们可以将 FittedBox 理解为合适的盒子&#xff0c;将其它布局放到FittedBox这样一个盒子中&#xff0c;从而实现 盒子里面的…

ceph高可用

配置基础环境 # 关闭防火墙 systemctl stop firewalld systemctl disable firewalld# 关闭selinux setenforce 0 sed -i s/^SELINUX.*/SELINUXdisabled/ /etc/selinux/config 安装基础环境 然后安装ceph的密钥&#xff0c;centos7和8都要执行&#xff0c;下面不特别说明都是c…

一文详解汽车电子LIN总线

0.摘要 汽车电子LIN总线不同于CAN总线。 LIN总线基本上是CAN总线的廉价补充&#xff0c;相比于CAN总线&#xff0c;它提供较低的可靠性和性能。同时LIN总线也是一个应用非常广泛的网络协议&#xff0c;并且越来越受欢迎。 再一次&#xff0c;我们准备了一个关于LIN总线的简要…

SurfaceFliger绘制流程

前景提要&#xff1a; 当HWComposer接收到Vsync信号时&#xff0c;唤醒DisSync线程&#xff0c;在其中唤醒EventThread线程&#xff0c;调用DisplayEventReceiver的sendObjects像BitTub发送消息&#xff0c;由于在SurfaceFlinger的init过程中创建了EventThread线程&#xff0c…

【Proteus仿真】【STM32单片机】便携式恒温箱设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用报警模块、LCD1602显示模块、DS18B20温度模块、加热制冷模块、按键模块、HC05蓝牙模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1…

Leetcode刷题详解——不同路径 II

1. 题目链接&#xff1a;63. 不同路径 II 2. 题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finis…

连铸生产线液压系统比例伺服阀放大器

连铸生产线液压系统是连铸机的关键组成部分&#xff0c;它由液压站组成&#xff0c;包括高压泵站、剪切机泵站、滑动水口站、塞棒液压站、中间罐车液压站和倾翻台液压站。这些站点通过管道连接&#xff0c;共同实现连铸机的各类动作&#xff0c;如升降、横移、定位、锁紧及辊缝…

TCP/IP(十七)实战抓包分析(一)ICMP

一 TCP实战抓包分析 网络排查案例 ① 抓包分析涉及的内容 关于&#xff1a; TCP理论知识和tcpdump命令的知识,前面已经铺垫过了,这里不再赘述下面罗列了TCP的重点知识 客户端工具&#xff1a; curl、wget、postman、telnet、浏览器、ncwget --bind-addressADDRESS 指定…

酷开科技,让家庭更有温度!

生活中总有一些瞬间&#xff0c;会让我们感到无比温暖和幸福。一个拥抱、一句问候、一杯热茶&#xff0c;都能让我们感受到家庭的温馨和关爱。酷开科技也用自己的方式为我们带来了独属于科技的温暖&#xff0c;通过全新的体验将消费者带进一个充满惊喜的世界&#xff0c;让消费…