力扣刷题总结 字符串(1)【反转法】

news2024/11/16 6:38:31

🔥博客主页: A_SHOWY
🎥系列专栏:力扣刷题总结录 数据结构  云计算  数字图像处理     

344.反转字符串eswap应用+双指针
541.反转字符串Ⅱm可以自己定义函数也可以直接reverse
151.反转字符串中的单词m局部翻转加全局翻转
卡码网 替换数字m找到数字的数量双指针应用
卡码网 右旋字符串e局部翻转加全局翻转应用

(1)344.反转字符串

344. 反转字符串icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-string/

class Solution {
public:
    void reverseString(vector<char>& s) {
for(int i = 0,j=s.size()-1; i< s.size()/2;i++,j--)
{
    swap(s[i],s[j]);
}

    }
};

1.本题目是最经典最基础的双指针法,可以直接用到swap库函数即可

2.在判断i的取值范围的时候,如果对于边界无法把握是否有等于号,想几个特殊的例子即可

(2)541.反转字符串Ⅱ

541. 反转字符串 IIicon-default.png?t=N7T8https://leetcode.cn/problems/reverse-string-ii/方法一:使用库函数reverse

class Solution {
public:
    string reverseStr(string s, int k) {
   for(int i =0; i < s.length();i += (2*k))
   {
       if(i+k<s.length()) reverse(s.begin() + i,s.begin() + i + k);
       else reverse(s.begin() + i, s.end());
   }
   return s;
    }
};

可以使用reverse库函数完成注意只需要注意循环的停止条件i += 2k,每隔2k跳一次,如果够k就局部前k个翻转,如果不够,就全部翻转.

方法二:自己定义翻转函数

class Solution {
public:
    
    void reverse(string& s, int start, int end)
    {
        for(int i = start,j = end;i < j ;i++,j--)
        {
            swap(s[i],s[j]);
        }
    }
string reverseStr(string s, int k) {
    for(int i = 0; i < s.length(); i += (2 * k))
    {
        if(i + k <= s.length()) reverse(s,i,i+k-1);
        else{
            reverse(s,i,s.length()-1);
        }
    }
    return s;
    }
};

1.使用string&作为函数参数表示传递的是字符串的引用,使用string&作为函数参数允许直接操作调用者提供的字符串,而不是复制一份新的字符串,这样可以提高效率并节省内存。

2.注意使用自己定义的翻转函数的时候,下标 = 第几位 - 1

3.这种方法就是在第一题的基础上一个应用,使用双指针构造这种全局的翻转

(3)151.反转字符串中的单词

151. 反转字符串中的单词icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-words-in-a-string/

对于删除多于的空格的操作,底下这种操作其实是O(n^2)的,erase时间复杂度是O(n),在for循环里所以为n方。

void removeextrething(string &s){
    //删除中间多余的空格
          for(int i = s.size - 1;i > 0; i--){
              if(s[i] = s[i-1] && s[i] == ' ')
              s.erase(s.begin() + i);
          }  
    //删除字符串最后的空格
          if(s[s.size()-1] == ' '&& s.size() > 0){
              s.erase(s.begin() + s.size() - 1);
          }
    //删除字符串最前面的空格
         if(s[0] ==' ' && s.size() > 0){
             s.erase(s.begin());
         }
    }

 那么使用双指针法来去移除空格,最后resize(重新设置)一下字符串的大小,就可以做到O(n)的时间复杂度。

void removeExtraSpaces(string& s) {
    int slowIndex = 0, fastIndex = 0; // 定义快指针,慢指针
    // 去掉字符串前面的空格
    while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
        fastIndex++;
    }
    for (; fastIndex < s.size(); fastIndex++) {
        // 去掉字符串中间部分的冗余空格
        if (fastIndex - 1 > 0
                && s[fastIndex - 1] == s[fastIndex]
                && s[fastIndex] == ' ') {
            continue;
        } else {
            s[slowIndex++] = s[fastIndex];
        }
    }
    if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') { // 去掉字符串末尾的空格
        s.resize(slowIndex - 1);
    } else {
        s.resize(slowIndex); // 重新设置字符串大小
    }
}

那么比较完整的代码如下: 

class Solution {
public:

    void removeExtrathing(string& s)//第一个函数删除多余空格
    {
          int slow = 0;
        for(int i = 0; i< s.size(); ++i){
            if(s[i] != ' ')//找出不是空格的开始操作
            {
                if(slow != 0){//slow不等于0就不是第一个单词 
                  s[slow++] = ' ';
                }
                while(i < s.size()&& s[i] != ' ') {
                    s[slow++] = s[i++];
                }
                
            }
        }
            s.resize(slow);
    }
    void reverse(string& s,int left,int right)//第二个函数反转字符串
    {
        for(int i = left,j = right;i < j;i++,j--)
        {
            swap(s[i],s[j]);
        }
    }
    string reverseWords(string s) {
        
        removeExtrathing(s);
        reverse(s,0,s.size() - 1);//先把整体反转
        int start = 0 ;
        for(int i = 0; i <= s.size();i++)//注意等于的情况
        {
            if(s[i] == ' ' || i == s.size())//有空格或者达到串尾说明一个单词结束
            {reverse(s,start,i-1);
            start = i+1;}
        }
         return s;
    }
    };

1.可以看到删除多余的空格可以一起讨论没必要分开讨论,当不是空格的时候,开始操作,可以联想到我们以前在学习一道移除元素的题目的思路,如果不清楚可以看这篇文章,让快指针走,遇到不要的元素就跳过,遇到要的就给慢指针。力扣刷题总结 数组(1)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/showy0/article/details/134212692?spm=1001.2014.3001.5501

   if(s[i] != ' ')//找出不是空格的开始操作

2.注意这里手动加入空格,当出现slow不等于0的时候就是不是第一个单词,给个空格,放到i传给慢指针语句的后面

if(slow != 0){//slow不等于0就是不是第一个单词 
                  s[slow++] = ' ';

3.第二个函数就是反转字符串和我们前面练习的两个题一模一样是一个应用,可以当作模板直接记住。

4.主函数的操作顺序是,先删除多余的空格,整体字符串反转,然后当出现空格或者最后的时候,单个单词的反转,整个题目结束。

(4)卡码网 替换数字

题目页面 (kamacoder.com)icon-default.png?t=N7T8https://kamacoder.com/problempage.php?pid=10641.整个题目的做题思路应该比较清晰,首先第一步是找到一共有多少个数字(all)需要替换,第二步是重新给字符串新的空间(oldsize+ 5 * all),然后进行双指针,快指针指向新的字符串的末尾,慢指针指向旧的字符串的末尾,同时向前移动。此题的关键是双指针的应用

2.至于为什么不指向字符串的开头,因为如果在开头,在遍历的过程中添加元素需要所有元素跟着移动,而且不用申请新的数组。

#include<iostream>
using namespace std;
int main()
{
    string s;
    int all = 0;
while(cin>>s){
    int oldSize = s.size();
//先统计一下数字数量
 for(int i = 0;i< s.size();i++)
 {
    if(s[i] >= '0' && s[i] <= '9'){
        all++;
    }
  }

    s.resize(s.size() + 5 * all);
   int newSize = s.size();
    for(int i = oldSize-1,j = newSize-1;i < j;i--,j--)
    {
        if(s[i] > '9' || s[i] < '0'){
            s[j] = s[i];
        }
        else{
            s[j] = 'r';
            s[j-1] = 'e';
            s[j-2] = 'b';
            s[j-3] = 'm';
            s[j-4] = 'u';
            s[j-5] = 'n';
            j -= 5;
        }
    }
}
cout<<s<<endl;
}

补充:关于字符串和数组,字符串是若干字符组成的有限序列,也可以理解为是一个字符数组。C++中,提供一个string类,string类会提供 size接口,可以用来判断string类字符串是否结束。例如:

string s = "abd";
for(int i = 0; i < s.size();i++){
}

(5)卡码网 右旋字符串

题目页面 (kamacoder.com)icon-default.png?t=N7T8https://kamacoder.com/problempage.php?pid=10651.这个题目其实就是一个整体和局部的反转操作的组合,那么如果先整体进行反转,再分成两部分局部进行反转的话就可以实现

2.需要注意的是

  • s.begin() + n 表示容器 s 中第 n 个元素的迭代器(即从第 n+1 个元素开始的位置)。
  • s.end() 表示容器 s 的末尾迭代器。
  • 在C++的STL中,reverse() 函数中的第二个参数表示的是翻转操作的结束位置的下一个元素的位置。

方法一:先整体后局部反转 

#include<iostream>
#include<algorithm>//reverse
using namespace std;
int main(){
    int n;
    string s;
    cin>>n;
    cin>>s;
    int len = s.size();//先获取一下字符串长度
    reverse(s.begin(),s.end());
    reverse(s.begin(),s.begin() + n);
    reverse(s.begin() + n,s.end());
    cout<< s<<endl;
}

当然也可以先局部反转,然后再全局反转,但是这时要注意的是,前面部分反转的应该是len - n;后面反转n个,最后再全部反转

方法二:先局部后整体反转

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
    int n;
    string s;
    cin >> n;
    cin >> s;
    int len = s.size(); //获取长度
    reverse(s.begin(), s.begin() + len - n); // 先反转前一段,长度len-n ,注意这里是和版本一的区别
    reverse(s.begin() + len - n, s.end()); // 再反转后一段
    reverse(s.begin(), s.end()); // 整体反转
    cout << s << endl;

}

 拓展:左旋转

那么假如我们要实现左翻转,其实思路是一样的,先整体后局部或者先局部后整体,无非是旋转区间的区别,思路比较简单的做法是先局部后整体,如下

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
    int n;
    string s;
    cin >> n;
    cin >> s;
    int len = s.size(); //获取长度
    reverse(s.begin(), s.begin() + n); //  反转第一段长度为n 
    reverse(s.begin() + n, s.end()); // 反转第二段长度为len-n 
    reverse(s.begin(), s.end());  // 整体反转
    cout << s << endl;

}

那么字符串部分翻转以及翻转的应用的经典题目总结完毕了,下一篇总结关于KMP方法的具体解析和应用题目。

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

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

相关文章

05-微服务架构构建之六边形架构

文章目录 前言一、六边形架构的概念二、六边形架构的特点三、微服务架构的良好实践总结 前言 通过前面的学习&#xff0c;我们掌握了微服务架构的基本组件等内容。在选择适合每个微服务的架构时&#xff0c;六边形架构“天然”成为每个微服务构建的最佳选择。 一、六边形架构的…

【征稿倒计时十天,ACM独立出版,有确定的ISBN号,ei检索稳且快】

2023 人工智能、系统与网络安全国际学术会议 (AISNS 2023&#xff09; 2023 International Conference on Artificial Intelligence, Systems and Network Security 由西南科技大学计算机科学与技术学院主办的2023人工智能、系统与网络安全国际学术会议 (AISNS 2023&#xff0…

Python开发运维:Python 3.8 常用标准库

目录 一、理论 1.Python3.8 标准库 2.常用标准库 二、问题 1.Python 正则表达式如何实现 一、理论 1.Python3.8 标准库 &#xff08;1&#xff09;官网 Python 标准库 — Python 3.8.17 文档 &#xff08;2&#xff09;其他版本下拉列表查询 2.常用标准库 &#xff0…

事务管理 springboot

事务是一组操作的集合 它是一个不可分割的工作单位 这些操作 要么同时成功要么同时失败 Spring事务管理 #Spring事务管理日志 logging: level: org.springframework.jdbc.support.JdbcTransactionManager: debug

qt使用wimlib-imagex,做windows系统备份还原

wimlib-imagex是个第三方工具&#xff0c;可对系统映像进行操作&#xff0c;下载地址&#xff1a; https://wimlib.net/downloads/index.html 程序主要用到以下这两个文件&#xff1a;libwim-15.dll和wimlib-imagex.exe wimlib-imagex.exe的调用命令参数&#xff0c;可以通过…

Opencv打开图片

cv.imread() oepncv中使用cv.imread函数读取图片&#xff0c;并打开窗口显示&#xff0c;以下是示例代码 import cv2 as cv import numpy as np from matplotlib import pyplot as pltsrc cv.imread("demo.jpg")#blue, green red cv.namedWindow("input ima…

数据库系统概论期末经典大题讲解(用关系代数进行查询)

今天也是结束的最为密集的考试周&#xff0c;在分析过程中自己也有些许解题的感悟&#xff0c;在此分享出来&#xff0c;希望能帮到大家期末取得好成绩。 一.专门的关系运算 1.选择&#xff08;σ&#xff09; 选择操作符用于从关系中选择满足特定条件的元组 例如&#xff0c;…

前端——html拖拽原理

文章目录 ⭐前言⭐draggable属性&#x1f496; api&#x1f496; 单向拖动示例&#x1f496; 双向拖动示例 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 前端——html拖拽原理。 vue3系列相关文章&#xff1a; vue3 fastapi 实现选择目录所有文…

安装you-get(mac)

1、首先要有python环境 2、更新pip python -m pip install --upgrade pip 3、安装you-get pip install you-get;

面试多线程八股文十问十答第二期

面试多线程八股文十问十答第二期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1.进程和线程的区别 概念不同&#xff1a;进程是操作系统中的一个独立执行单元&a…

redis 安装在liunx安装和常用文件配置

文章目录 安装配置文件设置测试启动服务连接服务 安装 1.官网下载压缩包: https://redis.io/download/ 2.将压缩包上传到Linux环境中 解压: tar -xvf redis-xxxxx 3.liunx 需要c的环境 yum -y install gcc-c4.进入redis文件夹 make && make install5.推荐不是必须…

【滤波第二期】中值滤波的原理和C代码

中值滤波是一种非线性数字滤波技术&#xff0c;主要应用于信号处理和图像处理领域&#xff0c;用于减小信号中的噪声和离群值。中值滤波的核心思想是通过计算一组数据点的中间值&#xff0c;以抑制脉冲噪声等离群值的影响&#xff0c;从而实现信号的平滑处理。 1&#xff0c;中…

spring cloud nacos整合gateway

文章目录 gateway快速入门创建gateway服务&#xff0c;引入依赖编写启动类编写基础配置和路由规则重启测试网关路由的流程图 断言工厂过滤器工厂路由过滤器的种类请求头过滤器默认过滤器总结 全局过滤器全局过滤器作用自定义全局过滤器过滤器执行顺序 跨域问题什么是跨域问题解…

浅谈Django之单元测试

一、什么是单元测试 单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。如果测试通过则说明我们这个函数或功能能够正常工作&#xff0c;如果失败要么测试用例不正确&#xff0c;要么函数有bug需要修复。 二、如何使用单元测试 from django.test imp…

使用UART和USART在STM32上进行双向通信

在本文中&#xff0c;我们将深入了解如何在STM32上使用UART&#xff08;通用异步收发传输器&#xff09;和USART&#xff08;通用同步异步收发传输器&#xff09;实现双向通信。UART和USART是常见的串口通信协议&#xff0c;通常用于与其他设备进行数据传输。我们将重点介绍如何…

抓取Chrome所有版本密码

谷歌浏览器存储密码的方式 在使用谷歌浏览器时,如果我们输入某个网站的账号密码,他会自动问我们是否要保存密码,以便下次登录的时候自动填写账号和密码 在设置中可以找到登录账户和密码 也可以直接看密码,不过需要凭证 这其实是windows的DPAPI机制 DPAPI Data Protection Ap…

ESP32 freeRTOS笔记 参数传递、任务优先级

一、四种参数传递方式 1.1 整数传递 使用 (void *) 任何类型传递参数&#xff0c;通过地址传递给任务。 #include <stdio.h> #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h"void myTask(void *pvP…

leetcode算法之栈

目录 1.删除字符串中的所有相邻重复项2.比较含退格的字符串3.基本计算器II4.字符串解码5.验证栈序列 1.删除字符串中的所有相邻重复项 删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {string ret;//使用数组模拟栈操作for(auto …

element的el-date-picker时间控件,限制选择范围区间天数并且当前之后的日期不可选

element的el-date-picker时间控件&#xff0c;限制选择范围区间天数并且当前之后的日期不可选 HTML部分代码 <el-date-pickerv-model"dateRange"type"datetimerange"value-format"yyyy-MM-dd HH:mm:ss"range-separator"至"start-p…

Python小案例:打印10以内的素数

解析 1、利用循环控制范围&#xff08;1,100&#xff09; 2、通过循环判断素数 3、利用标记法进行打印素数 代码 #求1——100之间的素数 for i in range(2,101):is_primeNum Truefor j in range(2,i):if i%j 0:# print(f"{i}不是素数")is_primeNum Falseif is_…