【算法-字符串2】替换空格 + 反转单词

今天,带来字符串相关算法的讲解。文中不足错漏之处望请斧正!

理论基础点这里


1. 替换空格

题目描述:请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
来源:力扣(LeetCode)
难度:简单
提示:
0 <= s 的长度 <= 10000
示例 1:
输入:s = “We are happy.” 输出:“We%20are%20happy.”

题意转化

把字符串内的所有' '替换为%20.

解决思路(抽象)

使用额外空间

创建一个空字符串, 遍历给定字符串s, 遇到字符的时候直接插入空字符串, 遇到空格的时候插入%20.

不使用额外空间

不用额外空间就要扩容:统计空格个数,每个空格替换成“%20”,就意味着每个空格都需要额外两个字符的空间。

扩容后,从后向前替换

为什么是从后向前?因为从前向后替换数组元素,每次替换完都要把后面所有元素往后移动,这就是O(n^2)的复杂度了。

编程实现(具体)

使用额外空间

class Solution {
public:string replaceSpace(string s) {string ret;for(char &ch : s) {if(ch == ' ') ret += "%20";else ret += ch;}return ret;}
};

不使用额外空间

class Solution {
public:string replaceSpace(string s) {// 扩容int count = 0; //空格个数for(char &ch : s) if(ch == ' ') ++count;int oldSize = s.size();s.resize(s.size() + count * 2);int newSize = s.size();// 从后向前替换for(int i = oldSize - 1, j = newSize - 1; i < j; --i, --j) {if(s[i] != ' ') {s[j] = s[i];} else {s[j] = '0';s[j - 1] = '2';s[j - 2] = '%';j -= 2; //多了两次操作,j指针对应移动}}return s;}
};

2. 反转单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 1:

输入:s = “the sky is blue”
输出:“blue is sky the”
示例 2:

输入:s = " hello world "
输出:“world hello”
解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:

输入:s = “a good example”
输出:“example good a”
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

提示:

1 <= s.length <= 104
s 包含英文大小写字母、数字和空格 ’ ’
s 中 至少存在一个 单词

进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。

题意转化

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串.

解决思路(抽象)

首先, 要保证单词之间用单个空格连接(头尾没有空格).

原地处理的话, 可以使用双指针重新填充字符串:

  • fast:遍历s拿字符(遇到空格就跳过)
  • slow:从头填充合法字符串

简单说, 每次遇到空格就自己把单词填充上, 再手动添加一个空格, 就可以满足题目要求.

单词顺序颠倒, 我们无法直接实现, 但我们能做什么?

  • 颠倒字符串顺序
  • 颠倒单个单词顺序

前者就可以颠倒单词顺序, 只不过会让单个单词也颠倒, 我们再次颠倒每个单词, 不就得到了题目要求的字符串了吗.
比如 如 hello world , 整体反转后是 dlrow olleh;然后对单词反转 world hello .
简单说, 先总体反转, 再局部反转.

编程实现(具体)

最后一个单词, 可以在反转单词内部顺序的循环中处理, 也可以跳出循环单独处理.

最后一个单词反转单词内部顺序的循环中处理:

class Solution {
public:string reverseWords(string s) {//双指针重新填充字符串int slow; // 填充字符串int fast; // 遍历sfor (slow = 0, fast = 0; fast < s.size(); ++fast) {if (s[fast] == ' ') continue; // 如果是空格就跳过// 填充当前单词while (fast < s.size() && s[fast] != ' ') s[slow++] = s[fast++];// 填充空格(只有最后一个单词后不需要填充)s[slow++] = ' ';}s.resize(slow - 1); // 去掉多余的空格(最后一个单词后不需要填充, 但我们默认填充了)cout << "处理后的字符串: " << s << endl;// 整体反转reverse(s.begin(), s.end());// 局部反转int wordBegin = 0;int wordEnd= 0;while (wordEnd <= s.size()) {if (s[wordEnd] == ' ' || wordEnd == s.size()) {reverse(s.begin() + wordBegin, s.begin() +wordEnd);wordBegin = wordEnd + 1;wordEnd = wordBegin;}++wordEnd;}return s;}
};

最后一个单词跳出循环单独处理:

class Solution {
public:string reverseWords(string s) {//双指针重新填充字符串int slow; // 填充字符串int fast; // 遍历sfor (slow = 0, fast = 0; fast < s.size(); ++fast) {if (s[fast] == ' ') continue; // 如果是空格就跳过// 填充当前单词while (fast < s.size() && s[fast] != ' ') s[slow++] = s[fast++];// 填充空格(只有最后一个单词后不需要填充)s[slow++] = ' ';}s.resize(slow - 1); // 去掉多余的空格(最后一个单词后不需要填充, 但我们默认填充了)cout << "处理后的字符串: " << s << endl;// 整体反转reverse(s.begin(), s.end());// 局部反转int wordBegin = 0;int wordEnd= 0;while (wordEnd < s.size()) {if (s[wordEnd] == ' ') {reverse(s.begin() + wordBegin, s.begin() +wordEnd);wordBegin = wordEnd + 1;wordEnd = wordBegin;}++wordEnd;}reverse(s.begin() + wordBegin, s.begin() +wordEnd); // 反转最后一个单词return s;}
};

今天的分享就到这里了,感谢您能看到这里。

这里是培根的blog,期待与你共同进步!

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

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

相关文章

Lettuce使用详解

简介特点连接池连接池特点连接池管理连接池优势连接池配置参数 监控常用监控工具通过JMX监控通过Prometheus监控 代码示例拓展springboot中通过jmx上报到Prometheus代码示例更多Redis相关内容 简介 Lettuce 是一个高级的、线程安全的 Redis 客户端&#xff0c;用于与 Redis 数…

深度学习基础概念

1. 神经网络基础 神经元&#xff08;Neuron&#xff09;&#xff1a; 了解神经网络的基本组成单元。激活函数&#xff08;Activation Function&#xff09;&#xff1a; 学习常见的激活函数&#xff0c;如Sigmoid、ReLU等&#xff0c;以及它们在神经网络中的作用。前馈神经网络…

An issue was found when checking AAR metadata

一、报错信息 An issue was found when checking AAR metadata:1. Dependency androidx.activity:activity:1.8.0 requires libraries and applications that depend on it to compile against version 34 or later of the Android APIs.:app is currently compiled against …

Python 异步套接字编程

异步套接字编程是异步编程在网络通信中的应用&#xff0c;它使用异步 IO 操作和事件循环来实现高并发的网络应用。Python 中的 asyncio 模块提供了对异步套接字编程的支持&#xff0c;以下是异步套接字编程的一些重要概念和使用方法&#xff1a; 1. 异步套接字服务器&#xff…

git与ssh多账户共存

git与ssh多账户共存 前言git多账户ssh多公钥参考 前言 在使用git与ssh时&#xff0c;经常会遇到多个账户共存的情况 例如使用不同的公钥登陆到不同的服务&#xff1b;使用不同的git信息进行commit git多账户 在默认情况下 git的信息存在 ~/.gitconfig 可以使用命令查看 git…

关于elementui和ant design vue无法禁止浏览器自动填充问题

以and design vue 为例&#xff1a; 图标用来显隐账号密码 html&#xff1a; <a-form-model-item label"账号密码:" prop"password"><a-input v-if"passwordTab" ref"passwordInput" v-model"form.password" typ…

详解最长公共子序列问题(三种方法)

这里&#xff0c;为了更方便地解释&#xff0c;我以洛谷上的一道典型题目为例&#xff0c;为大家讲解处理最长公共子序列问题的几种常见方法。这道题目中规定了两个子序列的长度相等&#xff0c;如果遇到不等的情况&#xff0c;也只需要对长度稍作修改即可&#xff0c;算法思想…

qs-一个序列化和反序列化的JavaScript库

起因 一个业务场景中&#xff0c;最终得到一串字符"status[0]value1&status[1]value2" 通过解析&#xff0c;理应得到一个数组&#xff0c;却得到一个对象 于是展开问题排查 最终发现是qs.parse 这个地方出了问题 排查结果 qs解析这种带下标的字符串时&#xff…

基于python的NBA球员数据可视化分析的设计与实现

完整下载&#xff1a;基于python的NBA球员数据可视化分析的设计与实现.docx 基于python的NBA球员数据可视化分析的设计与实现 Design and Implementation of NBA Player Data Visualization Analysis based on Python 目录 目录 2 摘要 3 关键词 4 第一章 引言 4 1.1 研究背景 …

【Java 进阶篇】Redis 命令操作:轻松掌握基本操作

Redis是一款高性能的键值对存储系统&#xff0c;以其快速、灵活的特性而备受开发者推崇。本文将详细介绍Redis的基本命令操作&#xff0c;包括键值操作、数据查询、事务处理等方面&#xff0c;帮助初学者更好地理解和使用Redis。 基本命令 1. 键值操作 1.1 SET&#xff1a;设…

spark shuffle 剖析

ShuffleExchangeExec private lazy val writeMetrics SQLShuffleWriteMetricsReporter.createShuffleWriteMetrics(sparkContext)private[sql] lazy val readMetrics SQLShuffleReadMetricsReporter.createShuffleReadMetrics(sparkContext)用在了两个地方&#xff0c;承接的是…

目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】SLAM(基础篇)(三)

目录 前言 移动机器人视觉SLAM回环检测 01 回环检测问题描述 02 主流回环检测方法 2.1 根据路标点先验信息

【Flink】Standalone运行模式

独立模式是独立运行的&#xff0c;不依赖任何外部的资源管理平台&#xff1b;当然独立也是有代价的&#xff1a;如果资源不足&#xff0c;或者出现故障&#xff0c;没有自动扩展或重分配资源的保证&#xff0c;必须手动处理。所以独立模式一般只用在开发测试或作业非常少的场景…

Ps:参考线

参考线 Guides用于帮助精确地定位图像或元素&#xff0c;显示为浮动在图像上的非打印线&#xff0c;可以移动或移除&#xff0c;还可以临时锁定。 Ps 中的参考线可分为三大类&#xff1a;画布参考线、画板参考线和智能参考线。 可在“首选项/参考线、网格和切片”中设置参考线的…

C 标准库 - <stddef.h>和<stdio.h>详解

目录 C 标准库 - 简介 库变量 库宏 实例 C 标准库 - 简介 库变量 库宏 库函数 实例 C 标准库 - <stddef.h> 简介 <stdio.h> 是 C 语言中的一个标准库&#xff0c;它提供了一些常用的函数和类型定义&#xff0c;用于处理与大小相关的操作。 库变量 …

深信服防火墙路由模式开局部署-手把手教学(小白篇)

PS&#xff1a;深信服的设备只有400能够通过console连接&#xff0c;一般用户是无法连接的&#xff0c;所以大家不要妄想着从Console连接设备了&#xff0c;开局就通过MANAGE进入Web就可以 接通电源后&#xff0c;开机拿一根网线&#xff0c;一端连接防火墙的MANAGE口&#xf…

uniapp uni.navigateBack返回后刷新页面数据

方法1: 父页面设置钩子函数(onBackPress): 页面简介 | uni-app官网 适用于刷新多处数据 onBackPress(options) {this.refreshData(); }, methods:{refreshData: function() {//加载数据}, }, 方法2: 返回加success回调 uni.navigateBack({delta: 1, //返回层数&#xff0…

【C++】泛型编程 ⑭ ( 类模板示例 - 数组类模板 | 容器思想 | 自定义类可拷贝 - 深拷贝与浅拷贝 | 自定义类可打印 - 左移运算符重载 )

文章目录 一、容器思想1、自定义类可拷贝 - 深拷贝与浅拷贝2、自定义类可拷贝 - 代码示例3、自定义类可打印 - 左移运算符重载 二、代码示例1、Array.h 头文件2、Array.cpp 代码文件3、Test.cpp 主函数代码文件4、执行结果 一、容器思想 1、自定义类可拷贝 - 深拷贝与浅拷贝 上…

百战python02-语言元素

文章目录 指令与程序变量与类型变量命名变量的使用运算符赋值运算符比较运算符和逻辑运算符练习1:华氏温度转换为摄氏温度练习2:输入圆的半径计算计算周长和面积练习3:输入年份判断是不是闰年字符串常用操作注:需要对python有基本了解,可查看本作者python基础专栏,有任何问…

大模型生态新篇章:以AI Agent为引,助企业创新应用落地

文 | 智能相对论 作者 | 沈浪 以聊天机器人、虚拟助手、智能客服等为代表的对话式人工智能 (Conversational AI Agents ) 在具体服务场景中的应用已经十分普遍。今年以来&#xff0c;随着大模型技术的爆发与加持&#xff0c;对话式AI被市场赋予了更高的期望。 “所有行业都值…