当前位置: 首页 > news >正文

LeetCode刷题------字符串

目录

LeetCode:344.反转字符串

LeetCode:541. 反转字符串II

LeetCode:剑指Offer 05.替换空格

LeetCode:151.翻转字符串里的单词

LeetCode:剑指Offer58-II.左旋转字符串

LeetCode:28. 实现 strStr()

LeetCode:459.重复的子字符串



定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。

var reverseString = function(s) {let l = -1, r = s.length;while(++l < --r) {[s[l], s[r]] = [s[r], s[l]];}};

LeetCode:541. 反转字符串II

var reverseStr = function(s, k) {let resArr = s.split("");for (let i=0; i<s.length; i+=2*k) {let l = i-1, r = i + k > s.length ? s.length : i + k;while(++l < --r) {[resArr[l], resArr[r]] = [resArr[r], resArr[l]];}}return resArr.join("");};

LeetCode:剑指Offer 05.替换空格

从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
 var replaceSpace = function(s) {// 字符串转为数组const strArr = Array.from(s);let count = 0;// 计算空格数量for(let i = 0; i < strArr.length; i++) {if (strArr[i] === ' ') {count++;}}let left = strArr.length - 1;let right = strArr.length + count * 2 - 1;while(left >= 0) {if (strArr[left] === ' ') {strArr[right--] = '0';strArr[right--] = '2';strArr[right--] = '%';left--;} else {strArr[right--] = strArr[left--];}}// 数组转字符串return strArr.join('');
};

LeetCode:151.翻转字符串里的单词

提高一下本题的难度:不要使用辅助空间,空间复杂度要求为O(1)。不能使用辅助空间之后,那么只能在原字符串上下功夫了。想一下,我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了。所以解题思路如下:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转

举个例子,源字符串为:"the sky is blue "

  • 移除多余空格 : "the sky is blue"
  • 字符串反转:"eulb si yks eht"
  • 单词反转:"blue is sky the"
 var reverseWords = function(s) {// 字符串转数组const strArr = Array.from(s);// 移除多余空格removeExtraSpaces(strArr);// 翻转reverse(strArr, 0, strArr.length - 1);let start = 0;for(let i = 0; i <= strArr.length; i++) {if (strArr[i] === ' ' || i === strArr.length) {// 翻转单词reverse(strArr, start, i - 1);start = i + 1;}}return strArr.join('');
};// 删除多余空格
function removeExtraSpaces(strArr) {let slowIndex = 0;let fastIndex = 0;while(fastIndex < strArr.length) {// 移除开始位置和重复的空格if (strArr[fastIndex] === ' ' && (fastIndex === 0 || strArr[fastIndex - 1] === ' ')) {fastIndex++;} else {strArr[slowIndex++] = strArr[fastIndex++];}}// 移除末尾空格strArr.length = strArr[slowIndex - 1] === ' ' ? slowIndex - 1 : slowIndex;
}// 翻转从 start 到 end 的字符
function reverse(strArr, start, end) {let left = start;let right = end;while(left < right) {// 交换[strArr[left], strArr[right]] = [strArr[right], strArr[left]];left++;right--;}
}

LeetCode:剑指Offer58-II.左旋转字符串

// 版本一var reverseLeftWords = function(s, n) {const length = s.length;let i = 0;while (i < length - n) {s = s[length - 1] + s;i++;}return s.slice(0, length);
};// 版本二:在原字符串上修改var reverseLeftWords = function (s, n) {/** Utils */function reverseWords(strArr, start, end) {let temp;while (start < end) {temp = strArr[start];strArr[start] = strArr[end];strArr[end] = temp;start++;end--;}}/** Main code */let strArr = s.split('');let length = strArr.length;reverseWords(strArr, 0, length - 1);reverseWords(strArr, 0, length - n - 1);reverseWords(strArr, length - n, length - 1);return strArr.join('');
};

LeetCode:28. 实现 strStr()

本题是KMP 经典题目。KMP主要应用在字符串匹配上。KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。所以如何记录已经匹配的文本内容,是KMP的重点,也是next数组肩负的重任。

next数组就是一个前缀表。前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀

前缀表是如何记录的呢?首先要知道前缀表的任务是当前位置匹配失败,找到之前已经匹配上的位置,再重新匹配,此也意味着在某个字符失配时,前缀表会告诉你下一步匹配中,模式串应该跳到哪个位置。

构造next数组其实就是计算模式串s,前缀表的过程。 主要有如下三步:

  1. 初始化
  2. 处理前后缀不相同的情况
  3. 处理前后缀相同的情况
// 前缀表统一减一var strStr = function (haystack, needle) {if (needle.length === 0)return 0;const getNext = (needle) => {let next = [];let j = -1;next.push(j);for (let i = 1; i < needle.length; ++i) {while (j >= 0 && needle[i] !== needle[j + 1])j = next[j];if (needle[i] === needle[j + 1])j++;next.push(j);}return next;}let next = getNext(needle);let j = -1;for (let i = 0; i < haystack.length; ++i) {while (j >= 0 && haystack[i] !== needle[j + 1])j = next[j];if (haystack[i] === needle[j + 1])j++;if (j === needle.length - 1)return (i - needle.length + 1);}return -1;
};// 前缀表统一不减一var strStr = function (haystack, needle) {if (needle.length === 0)return 0;const getNext = (needle) => {let next = [];let j = 0;next.push(j);for (let i = 1; i < needle.length; ++i) {while (j > 0 && needle[i] !== needle[j])j = next[j - 1];if (needle[i] === needle[j])j++;next.push(j);}return next;}let next = getNext(needle);let j = 0;for (let i = 0; i < haystack.length; ++i) {while (j > 0 && haystack[i] !== needle[j])j = next[j - 1];if (haystack[i] === needle[j])j++;if (j === needle.length)return (i - needle.length + 1);}return -1;
};

LeetCode:459.重复的子字符串

//前缀表统一减一var repeatedSubstringPattern = function (s) {if (s.length === 0)return false;const getNext = (s) => {let next = [];let j = -1;next.push(j);for (let i = 1; i < s.length; ++i) {while (j >= 0 && s[i] !== s[j + 1])j = next[j];if (s[i] === s[j + 1])j++;next.push(j);}return next;}let next = getNext(s);if (next[next.length - 1] !== -1 && s.length % (s.length - (next[next.length - 1] + 1)) === 0)return true;return false;
};//前缀表统一不减一var repeatedSubstringPattern = function (s) {if (s.length === 0)return false;const getNext = (s) => {let next = [];let j = 0;next.push(j);for (let i = 1; i < s.length; ++i) {while (j > 0 && s[i] !== s[j])j = next[j - 1];if (s[i] === s[j])j++;next.push(j);}return next;}let next = getNext(s);if (next[next.length - 1] !== 0 && s.length % (s.length - next[next.length - 1]) === 0)return true;return false;
};

相关文章:

LeetCode刷题------字符串

目录 LeetCode&#xff1a;344.反转字符串 LeetCode&#xff1a;541. 反转字符串II LeetCode&#xff1a;剑指Offer 05.替换空格 LeetCode&#xff1a;151.翻转字符串里的单词 LeetCode&#xff1a;剑指Offer58-II.左旋转字符串 LeetCode&#xff1a;28. 实现 strStr() …...

区块链技术与应用2——BTC-数据结构

文章目录比特币中的数据结构1. 区块链&#xff08;block chain&#xff09;2. 默克尔树&#xff08;Merkle tree&#xff09;3.哈希指针的问题比特币中的数据结构 1. 区块链&#xff08;block chain&#xff09; 哈希指针&#xff1a; &#xff08;1&#xff09;保存数值的位置…...

BiseNet v1论文及其代码详解

来源&#xff1a;投稿 作者&#xff1a;蓬蓬奇 编辑&#xff1a;学姐 BiSeNet v1说明&#xff1a; 文章链接&#xff1a;https://arxiv.org/abs/1808.00897 官方开源代码&#xff1a;https://github.com/CoinCheung/BiSeNet &#xff08;本文未使用&#xff09; 文章标题&am…...

(超详细)Navicat的安装和激活,亲测有效

步骤一&#xff1a;准备安装包 下载Navicat&#xff0c;我用的v15最好一致&#xff08;私信可以发你安装包和注册码&#xff09;步骤二&#xff1a;关闭杀毒软件&#xff0c;然后需要断掉网络&#xff08;一定断网&#xff09; 步骤三&#xff1a;一路next安装&#xff0c;安装…...

JDY-31蓝牙模块使用指南

前言 本来是想买个hc-05&#xff0c;这种非常常用的模块&#xff0c;但是在优信电子买的时候&#xff0c;说有个可以替代的&#xff0c;没注意看&#xff0c;买回来折腾半天。 这个模块是从机模块&#xff0c;蓝牙模块分为主机从机和主从一体的&#xff0c;主机与从机的区别就…...

【2023】华为OD机试真题Java-题目0211-租车骑绿道

租车骑绿道 题目描述 部门组织绿道骑行团建活动。租用公共双人自行车骑行,每辆自行车最多坐两人、最大载重 M M M。 给出部门每个人的体重,请问最多需要租用多少双人自行车。 输入描述 第一行两个数字 m m m、...

leetcode: 3Sum

leetcode: 3Sum1. 题目描述2. 思考3. 解题3. 总结1. 题目描述 Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i ! j, i ! k, and j ! k, and nums[i] nums[j] nums[k] 0. Notice that the solution set must not contain …...

【Python学习笔记】26.Python3 输入和输出(2)

前言 本章节继续介绍Python的输入输出。 文件对象的方法 本节中剩下的例子假设已经创建了一个称为 f 的文件对象。 f.read() 为了读取一个文件的内容&#xff0c;调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。 size 是一个可选的数字类型的…...

vue项目第二天

项目中使用element-ui库中文网https://element.eleme.cn/#/zh-CN安装命令npm install element-ui安装按需加载babel插件npm install babel-plugin-component -Dnpm i //可以通过npm i 的指令让配置刷新重新配置一下项目中使用element-ui组件抽离文件中按需使用element ui &…...

Python爬虫零基础到进阶(课程说明)

Python爬虫零基础到进阶 课程介绍总结 学—练—问 跟着学、多做多练、不懂就问、坚持就是胜利&#xff01; 作业 飞书布置&#xff0c;作业提交放到群里&#xff0c;老师批改。 代码量 python基础&#xff1a; 十一次课&#xff0c;学会python。环境安装&#xff08;了…...

《C++ Primer Plus》第16章:string类和标准模板库(13)

复习题 考虑下面的声明&#xff1a; class RQ1{ private:char *st; // pointer to C-style string public:RQ1() { st new char [1];strcpy(st, "");}RQ1(const char * s) {st new char [strlen(s)1];strcpy(st, s);}RQ1(const RQ1 & rq) {st new char[strlen…...

材质笔记 - Simluate Solid Surface

光的行为 当光和物体相遇时&#xff0c;光会有三种行为&#xff1a;被物体反射、穿过物体&#xff08;物体是透明或半透明的&#xff09;或者被吸收。 高光反射和漫反射 高光反射&#xff08;Specular Reflection&#xff09;会在表面光滑且反光的物体上看到&#xff0c;比如镜…...

设计模式-值类型与引用类型、深拷贝与浅拷贝、原型模式详解

一. 值类型和引用类型 1. 前言 (1). 分类 值类型包括&#xff1a;布尔类型、浮点类型(float、double、decimal、byte)、字符类型(char)、整型&#xff08;int、long、short等&#xff09;、枚举(entum)、结构体(struct)。 引用类型&#xff1a;数组、字符串(string)、类、接口…...

ssm高校功能教室预约系统java idea maven

本网站所实现的是一个高校功能教室预约系统&#xff0c;该系统严格按照需求分析制作相关模块&#xff0c;并利用所学知识尽力完成&#xff0c;但是本人由于学识浅薄&#xff0c;无法真正做到让该程序可以投入市场使用&#xff0c;仅仅简单实现部分功能&#xff0c;希望日后还能…...

C语言学习笔记-强制类型转换

强制类型转换是通过类型转换运算来实现的。其一般形式为&#xff1a;&#xff08;类型说明符&#xff09;&#xff08;表达式&#xff09;其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。自动转换是在源类型和目标类型兼容以及目标类型广于源类型时发生一个类型…...

docker数据卷插件

在docker中&#xff0c;对接外部存储我们通常需要docker的数据卷插件。docker中简要可分为两类 docker卷插件和CSI插件&#xff0c;其中docker卷插件分为两个版本&#xff0c;旧版的传统插件(legacy plugin/non-managed plugin)和新版的托管插件(managed plugin)。下面分章节讨…...

第二章-线程(3)

线程一、线程的定义二、线程的实现一、线程的定义 线程&#xff1a; 线程是进程中的一个实体&#xff0c;是系统独立调度和分派的基本单位。 进程是资源的拥有者&#xff0c;线程是系统独立调度和分配的基本单位。 进程与线程的比较&#xff1a; 调度&#xff1a;线程调度快…...

C++学习记录——칠 类和对象(4)

文章目录1、const成员2、取地址及const取地址操作符重载3、构造函数续集1、初始化列表2、explicit关键字4、static成员5、匿名对象6、友元1.友元函数2、友元类7、内部类1、const成员 看一段代码 class A { public:void Print(){cout << _a << endl;} private:int…...

Python-项目实战--飞机大战-碰撞检测(8)

目标了解碰撞检测方法碰撞实现1.了解碰撞检测方法pygame提供了两个非常方便的方法可以实现碰撞检测&#xff1a;pygame.sprite.groupcollide()两个精灵组中所有的精灵的碰撞检测groupcollide(group1, group2, dokill1, dokill2, collided None) -> Sprite_dict如果将dokill…...

T06 成绩排序

查找和排序 题目&#xff1a;输入任意&#xff08;用户&#xff0c;成绩&#xff09;序列&#xff0c;可以获得成绩从高到低或从低到高的排列,相同成绩 都按先录入排列在前的规则处理。 示例&#xff1a; jack 70 peter 96 Tom 70 smith 67 从高到低 成…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析&#xff1a;AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github&#xff1a;https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...