【leetcode 力扣刷题】双指针///原地扩充线性表

news2024/11/25 2:52:43

双指针///原地扩充线性表

  • 剑指 Offer 05. 替换空格
    • 定义一个新字符串
    • 扩充字符串,原地替换
    • 思考

剑指 Offer 05. 替换空格

题目链接:剑指 Offer 05. 替换空格
题目内容:
在这里插入图片描述
这是一道简单题,理解题意,就是将字符串s中的空格‘ ’替换成‘%20’。需要注意:一个空格是一个char,替换成‘%20’是3个char

这里有两种思路:一种是定义一个新的string变量ss,ss是s替换空格后的版本;一种是先扩充s的长度,然后在s上替换空格。

定义一个新字符串

这个方法先定义一个新的字符串ss,需要申请额外的空间。从前往后遍历s的时候,如果s[i] != ‘ ’,ss[j] = s[i],直接复制s的元素;如果s[i] == ‘ ’,那么ss[j]/ss[j+1]/ss[j+2]分别赋值‘%’,‘2’,‘0’,直到遍历完s。
【注意】需要先遍历s,统计s中空格的数量,以确定ss的长度为s.size() + 2 * count
代码如下(C++):

lass Solution {
public:
    string replaceSpace(string s) {
    	//先统计s中的空格数量
        int count = 0;
        for(int i = 0; i < s.size(); i++){
            if(s[i] == ' ')
                count++;
        }
        //申请新的空间s.size()+2*count
        string ss(s.size()+2*count,' ');
        for(int i = 0, j = 0; i < s.size(); i++){
            if(s[i] == ' '){ //替换空格
                ss[j++] = '%';
                ss[j++] = '2';
                ss[j++] = '0';
            }
            else{
                ss[j++] = s[i];
            }
        }
        return ss;
    }
};

扩充字符串,原地替换

上面的方法很容易想到,但是需要额外申请s.size()+2*count的空间。是否有空间复杂度更低的方法呢?
如果将空格替换成其他字符比如’a’,那么可以直接从前往后【从后往前也是可以的】遍历字符串中的每个字符,如果s[i]==‘ ’,就s[i] = ‘a’。这道题可以这么做吗? 答案是不行的。如果是s[i] == ‘ ’后,s[i]和s[i+1]和s[i+2]分别赋值‘%’,‘2’,‘0’,那么本身的s[i+1]/s[i+2]的值就会被覆盖
但是从后往前遍历就可以!先把s长度扩充为替换后的长度s.size() + 2 * count。双指针一个front定位在s原长度的最后一个元素;behind定位在s新长度的最后一个元素。front逐步前移,遍历s中的字符;如果s[front] != ‘ ’→s[behind] = s[front];如果s[front] == ‘ ’→s[behind-2]/s[behind-1]/s[behind]分别赋值‘%’‘2’‘0’。
从后往前遍历,不存在上面提到的s中一些未被遍历的元素被覆盖的情况。 因为front始终是小于等于behind的,而只有behind小于了front才有未遍历元素被覆盖。小于说明front指针前还有空格要替换;等于就说明front前面的元素全都非空格。一开始front在behind前面2 * count个位置,不是空格时,front前移一个,behind也前移一个,两者距离不变;遇到空格时,front前移一个,behind变成了‘%20’后前移三个,两个距离减少2,也就是每替换一个空格behind就向front靠近2个下标位置。因此直到空格替换完,front都在behind前面。而s中只有front前面的元素是没有复制到新s中的,front后面的元素都已经被复制到了s中的新位置,因此不存在没有遍历的元素被覆盖掉的情况。
另外,注意循环条件是front<behind,front=behind相等即说明空格替换完毕。
代码如下(C++):

class Solution {
public:
    string replaceSpace(string s) {
        //统计空格数量
        int count = 0;
        for(int i = 0; i < s.size(); i++){
            if(s[i] == ' ')
                count++;
        }
        int original = s.size(); //保留原始长度
        s.resize(original + 2*count); //resize到新的长度,新增一截
        //注意循环条件是front<behind,front和behind相等即说明空格替换完毕
        for(int behind = s.size()-1, front = original -1; front<behind ; front--){
            if(s[front] == ' '){//替换空格
                s[behind--] = '0';
                s[behind--] = '2';
                s[behind--] = '%';
            }
            else
                s[behind--] = s[front];
        }
        return s;
    }
};

思考

这个题目不仅适用于string,对于其他可变长度的数据结构,比如vector也是可以的。先扩充,再利用双指针原地操作原元素,可以降低空间复杂度。

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

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

相关文章

windows系统依赖环境一键安装

window系统程序依赖库&#xff0c;可以联系我获取15958139685 脚本代码如下&#xff0c;写到1. bat文件中&#xff0c;双击直接运行&#xff0c;等待安装完成即可 Scku.exe -AVC.exe /SILENT /COMPONENTS"icons,ext\reg\shellhere,assoc,assoc_sh" /dir%1\VC

性能优化为什么那么重要

性能优化在计算机系统和软件开发中具有重要意义&#xff0c;是衡量工程师技术水平的试金石&#xff0c;是升职加薪必备技能&#xff0c;并且在各个技术领域都发挥举足轻重的作用。 嵌入式领域 嵌入式设备通常具有有限的硬件资源&#xff08;如 CPU、内存、存储空间等&#xff0…

命令行环境

sleep 20 延迟20秒 这个是操作系统的信号机制 ctrl z ^z可以恢复 jobs 可以查看 终端运行工作列表&#xff0c;bg可以将暂停的作业重新运行 通过kill暂停作业 通过 -KILL 之后才可以将 -HUP 作业悬挂起来 终端复路多用 会话 ^a p 上一个会话 ^ a n 下一个会话 别名 左右不能…

idea中创建springboot项目显示Spring Initializr Error

很长时间不创建springboot项目了,今天发现创建完成idea显示: Spring Initializr Error error:status:500项目中没有pom.xml文件.检查了一下原因是在创建的时候类型没有创建正确(之前记得都是默认),默认如下 需要选择创建maven完整工程那种,最下面那种只会生成pom.xml不会…

javaee spring 自动注入,如果满足条件的类有多个如何区别

如图IDrinkDao有两个实现类 方法一 方法二 Resource(name“对象名”) Resource(name"oracleDrinkDao") private IDrinkDao drinkDao;

《Java极简设计模式》第05章:原型模式(Prototype)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 源码地址&#xff1a;https://github.com/binghe001/java-simple-design-patterns/tree/master/j…

Unittest自动化测试框架vs Pytest自动化测试框架

引言 前面一篇文章Python单元测试框架介绍已经介绍了python单元测试框架&#xff0c;大家平时经常使用的是unittest&#xff0c;因为它比较基础&#xff0c;并且可以进行二次开发&#xff0c;如果你的开发水平很高&#xff0c;集成开发自动化测试平台也是可以的。而这篇文章主要…

Pico使用C/C++选择使用哪个I2C控制器,以及SDA和SCL针脚

本文一开始讲述了解决方案&#xff0c;后面是我做的笔记&#xff0c;用来讲述我的发现流程和探究的 Pico I2C 代码结构。 前提知识 首先要说明一点&#xff1a;Pico 有两个 I2C&#xff0c;也就是两套 SDA 和 SCL。这点你可以在针脚图中名字看出&#xff0c;比如下图的 Pin 4…

性能测试面试问题,一周拿3个offer不嫌多

性能测试的三个核心原理是什么&#xff1f; 1.基于协议。性能测试的对象是网络分布式架构的软件&#xff0c;而网络分布式架构的核心是网络协议 2.多线程。人的大脑是单线程的&#xff0c;电脑的cpu是多线程的。性能测试就是利用多线程的技术模拟多用户去负载 3.模拟真实场景。…

<C++> STL_容器适配器

1.容器适配器 适配器是一种设计模式&#xff0c;该种模式是将一个类的接口转换成客户希望的另外一个接口。 容器适配器是STL中的一种重要组件&#xff0c;用于提供不同的数据结构接口&#xff0c;以满足特定的需求和限制。容器适配器是基于其他STL容器构建的&#xff0c;通过…

关于类的隐形生成函数

https://www.youtube.com/watch?ve8Cw17p_BiU&listPL5jc9xFGsL8FWtnZBeTqZBbniyw0uHyaH&index6 https://www.youtube.com/watch?vKMSYmY74AEs&listPLE28375D4AC946CC3&index4 如果只有copy asignment operator, 那么default construct will be generated as…

复习之docker部署--项目实战

一、实验环境 1.安装7.6虚拟机 最小化安装&#xff0c;不安装图形&#xff01; 2.封装虚拟机 关闭selinux关闭防火墙关闭networkmanager配置网络&#xff0c;保证可以ssh修改主机名添加双向解析配置7.6网络仓库--安装常用的工具 配置完成后&#xff0c;在真机ssh虚拟机 如果…

webassembly003 GGML Tensor Library part-1

GGML ggml的函数 可以看到官方示例项目仅依赖于#include "ggml/ggml.h"&#xff0c; #include "common.h"&#xff0c;可以阅读ggml.h获取ggml的使用帮助 函数解释注释ggml_tensor多维张量按行主顺序存储。ggml_tensor结构包含每个维度中元素数&#xf…

哈夫曼编码(C++实现)

文章目录 1. 前言2. 固定长度编码3. 哈夫曼编码4. 哈夫曼解码5. 编码特点6. 代码实现7. 总结 1. 前言 在上一篇文章中&#xff0c;介绍了 哈夫曼树的概念及其实现 。 哈夫曼树有什么用途呢&#xff1f; —— 那就是用来创建哈夫曼编码&#xff08;Huffman Coding —— 一种二…

2.神经网络的实现

创建神经网络类 import numpy # scipy.special包含S函数expit(x) import scipy.special # 打包模块 import pickle# 激活函数 def activation_func(x):return scipy.special.expit(x)# 用于创建、 训练和查询3层神经网络 class neuralNetwork:# 初始化神经网络def __init__(se…

JUC的常见类

Callable interfacce 也是一种创建线程的方式 Runnable 能表示一个任务(run方法),返回void Callable 也能表示一个任务(call方法),返回一个具体的值,类型可以通过泛型参数来指定(object) 如果进行多线程操作,如果你只是关心多线程的执行过程,使用Runnable即可,如果是关心多线程…

Lottery抽奖项目第二章第二节:搭建DDD四层结构

搭建DDD四层结构 DDD&#xff1a;Domain Driven Design 描述&#xff1a;基于DDD架构构建&#xff0c;初始化搭建工程结构 本节是陆续搭建系统和编码的开始&#xff0c;我们会优先完成一个基础工程的创建。一般在互联网企业这部分工作可能不需要反复处理&#xff0c;只需要在…

自然语言处理(二):近似训练

近似训练 近似训练&#xff08;Approximate Training&#xff09;是指在机器学习中使用近似的方法来训练模型&#xff0c;以降低计算复杂度或提高训练效率。这种方法通常用于处理大规模数据集或复杂模型&#xff0c;其中精确的训练算法可能过于耗时或计算资源不足。 近似训练…

14张图带你了解Android14中的酷炫的功能

14张图带你了解Android14中的酷炫的功能 在近期的几次更新中&#xff0c;Android系统经历了重要的升级。Android 12通过Material UI改变了外观&#xff0c;使界面更加优化。随后&#xff0c;Android 13在Android 12的基础上进一步提升了用户体验&#xff0c;使系统更加流畅。现…

自己的第一个小程序《我们一起记账吧》

一&#xff0c;想法 为了控制自己不要乱花钱&#xff0c;曾经一段时间每天记账&#xff0c;当时用的是市面上比较受欢迎的一些记账工具&#xff0c;但大多数都是以个人角度来记账的&#xff0c;几乎没有以家庭为单位的多人协同记账类软件&#xff0c;虽然也有多人记账小程序&a…