leetcode刷题-字符串

目录

1、Reverse String 反转字符串

2、Reverse String II 反转字符串II

3、Reverse Words in a String 翻转字符串里的单词

4、Find the Index of the FirstOccurrence in a String

实现 strStr()

KMP算法

next数组如何建立

模式串和字符串匹配

5、Repeated Substring Pattern 重复的子字符串

1、Reverse String 反转字符串

Write a function that reverses a string. The input string is given as an array of characters s.

You must do this by modifying the input array in-place with O(1) extra memory.

Example 1:

Input: s = ["h","e","l","l","o"]
Output: ["o","l","l","e","h"]

Example 2:

Input: s = ["H","a","n","n","a","h"]
Output: ["h","a","n","n","a","H"]

Constraints:

  • 1 <= s.length <= 105
  • s[i] is a printable ascii character.
class Solution {public void reverseString(char[] s) {for(int i=0;i<s.length/2;i++){char tem=s[i];s[i]=s[s.length-i-1];s[s.length-i-1]=tem;}}
}

2、Reverse String II 反转字符串II

Given a string s and an integer k, reverse the first k characters for every 2k characters counting from the start of the string.

If there are fewer than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and leave the other as original.

Example 1:

Input: s = "abcdefg", k = 2
Output: "bacdfeg"

Example 2:

Input: s = "abcd", k = 2
Output: "bacd"

Constraints:

  • 1 <= s.length <= 10^4
  • s consists of only lowercase English letters.
  • 1 <= k <= 10^4
class Solution {public String reverseStr(String s, int k) {//自己想的方法,就需要额外判断一下// char[] ss=s.toCharArray();// int num=s.length()/k;//代表有几个k// //这里就包含了奇数个k,存在大于k,小于2k的情况// for(int i=0;i<num;i+=2){ //i=0 2 4 6//     for(int j=0;j<k/2;j++){//     //更换k个字符,记得j一定是从0开始,结束的是k/2,//     //因为只需要更换一般,j作用是移动//         char tem=ss[k*i+j];//每次交换的起始位置是0k 2k 4k 结束位置是0k+k-1,2k+k-1,4k+k-1//         ss[k*i+j]=ss[k*i+k-1-j];//这里面j的作用就用来移动//         ss[k*i+k-j-1]=tem;//     }// }// if(num%2==0){//代表有双倍的k,说明剩下的数小于k,需要全部反转//     int remain=s.length()%k;//7个//     for(int j=0;j<remain/2;j++){//j的作用还是移动,所以从0开始//          char tem=ss[s.length()-remain+j];//起始位置为数组总长度前remain个,不断+j//          ss[s.length()-remain+j]=ss[s.length()-1-j];//结束位置就是数组最后一个字符,不断-j//          ss[s.length()-1-j]=tem;//     }// }     // return new String(ss);//别人的方法,比较巧妙,也是每隔2k就反转,但是通过end判断够不够k个数据//无论数组处于哪种情况,起始位置都是每隔2k的位置开始,然后结束位置就看,//假设后面满足k个那就正常反转 不满足k个就按照数组尾部来//至于那种大于k,小于2k的也反转了,下一次就从下一个2k开始,但是超过数组长度了,就不会操作char[] ch = s.toCharArray();for(int i = 0;i < ch.length;i += 2 * k){int start = i;//起始位置0k 2k 4k 6k// 判断尾数够不够k个来取决end指针的位置//这一步很巧妙,如果尾部不够k个,end就为数组最后一个字符//针对小于k的情况可以解决int end = Math.min(ch.length - 1,start + k - 1);while(start < end){char temp = ch[start];ch[start] = ch[end];ch[end] = temp;start++;end--;}}return new String(ch);// 定义翻转函数,可以复用,减少代码量,i为起始位置,j为结束位置,保障i<j// public void reverse(char[] ch, int i, int j) {// for (; i < j; i++, j--) {//     char temp  = ch[i];//     ch[i] = ch[j];//     ch[j] = temp;// }}
}

3、Reverse Words in a String 翻转字符串里的单词

Given an input string s, reverse the order of the words.

word is defined as a sequence of non-space characters. The words in s will be separated by at least one space.

Return a string of the words in reverse order concatenated by a single space.

Note that s may contain leading or trailing spaces or multiple spaces between two words. The returned string should only have a single space separating the words. Do not include any extra spaces.

Example 1:

Input: s = "the sky is blue"
Output: "blue is sky the"

Example 2:

Input: s = "  hello world  "
Output: "world hello"
Explanation: Your reversed string should not contain leading or trailing spaces.

Example 3:

Input: s = "a good   example"
Output: "example good a"
Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string.

Constraints:

  • 1 <= s.length <= 104
  • s contains English letters (upper-case and lower-case), digits, and spaces ' '.
  • There is at least one word in s.

Follow-up: If the string data type is mutable in your language, can you solve it in-place with O(1) extra space?

class Solution {public String reverseWords(String s) {StringBuilder sb=new StringBuilder();int index=0;//这道题目还可以就是全部反转,再把每个单词逐个反转//第一种方法:(1)先清除尾部空字符(2)再定位一个单位左右边界,逐个插入新字符串// for(int i=s.length()-1;i>=0;i--){//     char c=s.charAt(i);//     if(c!=' '){//         index=i;//         break;//     }// }// for(int i=index;i>=0;i--){//     int end=i;//     while(i>=0&&s.charAt(i)!=' '){//         i--;//     }//     int begin=i;//     while(i>=0&&s.charAt(i)==' ')i--;//     i++;//     sb.append(s.substring(begin+1,end+1));//     sb.append(' ');// }// return new String(sb.substring(0,sb.length()-1));//第二种方法,直接在一个for循环操作for(int i=s.length()-1;i>=0;i--){while(i>=0&&s.charAt(i)==' ')i--;//这一步是为了把尾部空字符去掉int end=i;//定位单词的结尾while(i>=0&&s.charAt(i)!=' '){i--;}int begin=i;//定义单词的开始while(i>=0&&s.charAt(i)==' ')i--;//这一步是必须的,保证头部的空格除去i++;//这里需要加1// 可以使用sb.append(s.substring(begin+1,end+1));//最好不用substring方法,因为string类的substring方法是产生新得字符串for(int j=begin+1;j<end+1;j++){sb.append(s.charAt(j));}sb.append(' ');}return new String(sb.substring(0,sb.length()-1));//当然还可以使用char数组,不用substring方法,因为string类的substring方法是产生新得字符串}}

4、Find the Index of the FirstOccurrence in a String

实现 strStr()

Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:

Input: haystack = "sadbutsad", needle = "sad"
Output: 0
Explanation: "sad" occurs at index 0 and 6.
The first occurrence is at index 0, so we return 0.

Example 2:

Input: haystack = "leetcode", needle = "leeto"
Output: -1
Explanation: "leeto" did not occur in "leetcode", so we return -1.

class Solution {public int strStr(String haystack, String needle) {int[] next=new int[needle.length()];int j=0;//记得这里的j代表的就是最长的前后缀长度next[0]=0;//next[j]代表包含j之前的最长相等前缀后缀长度for(int i=1;i<needle.length();i++){//aabaafwhile(j>0&&needle.charAt(i)!=needle.charAt(j))j=next[j-1];//这里是当不相等时就需要j往后退if(needle.charAt(i)==needle.charAt(j)){j++;//相等时就代表在原来的最长相等字符串的基础上加1个长度}next[i]=j;}j=0;for(int i=0;i<haystack.length()&&j<needle.length();i++){//i是一直往前运动的while(j>0&&haystack.charAt(i)!=needle.charAt(j)){j=next[j-1];}if(haystack.charAt(i)==needle.charAt(j)){j++;}if(j==needle.length()){return i-needle.length()+1;}}return -1;}
}

KMP算法

关于为什么需要next数组,next数组作用是什么,大家去看其他博主介绍吧

这里主要想讲一下next数组如何建立的 ,还有怎么匹配模式串和字符串

next数组存储的是模式串每个字符的最长前后缀长度,next数组的长度和模式串长度相等

前缀定义:当前字符之前的从第一个字符开始但是不包括最后一个字符的连续字符串

后缀定义:当前字符之前的最后一个字符结束但是不包括第一个字符的连续字符串

例如 模式串aabaaf

next[0]我们就看模式串第一个字符a 前缀有谁,后缀有谁,可以看到前缀后缀是空的,因为前后缀分别不能包含第一个和最后一个字符,所以next[0]=0

next[1],对应就是模式串的aa字符串,前缀只有a  后缀只有a 很明显相同的长度就是只有1个,所以next[1]=1

next[2]对应字符串aab 前缀有 a 和 aa  后缀有ab和b 所以前后缀没有相等的,next[2]=0

next[3]对应aaba 前缀有a 、aa、aab 后缀有 aba、ba、a  所以只有一个a和a相等长度为1 next[1]=1

next[4]对应aabaa 前缀 a  aa  aab  aaba   后缀 a  aa  baa  abaa, 所以相等的最长前后缀字符串为aa 长度为2  next[4]=2 

next数组如何建立

变量i去遍历模式字符串  变量j代表最长前后缀字符串长度 假设模式串数组为p

1、初始化  j=0 next[0]=0  因为第一个字符都是前后缀相等长度为0

假设现在遍历到模式串的第i个字符,那么前面0~i-1个字符的next数组都已经求出了

可以看到,目前假设遍历到i  而next[i-1]=j   也就是那2个红色框

1、观察模式串p[j]和 p[i] 是否相等

(1)如果相等,说明下面的红色框加蓝色框也各自相等

那么模式串从0到i的最长公共前缀不就是j+1吗

所以代码 实现

if(needle.charAt(i)==needle.charAt(j)){j++;//相等时就代表在原来的最长相等字符串的基础上加1个长度}

(2)如果不相等,就需要回退j  记得我们要找的是最长相等前后缀,所以i是不动的,尾部字符一定包含,头部字符一定包含

那怎么回退j呢 

其实我们就是需要把红色框分别缩短,在2个红色框找到一个最长的前后缀长度,之后再继续比较p[i]和p[j]  也就是找到2个绿色框

因为之前的2个红色框是相等的,所以绿色框相等,那对应位置也会有一个绿色框,如下图,这4个框的长度相同,我们关键就是需要找出绿色框的长度,把j定位到那里去

然后就很巧妙的发现,2个绿色框长度一样,看下图,这不刚好就是next[j-1]吗

因此代码实现就这样,这个过程是循环的,不断的比较p[i]和p[j],直到相等,就回到相等的情况

while(j>0&&needle.charAt(i)!=needle.charAt(j))j=next[j-1];//这里是当不相等时就需要j往后退

模式串和字符串匹配

需要2个变量指针i 和 j分别指向模式串和字符串

(1)首先比较字符串和模式串每个字符,当相等的时候,就i++,j++, 记得这里用if就可以了,不需要用while循环,因为本身外面就是以字符串i来遍历的,整个过程中字符串只遍历一次,也就是i一直往前运动的

如果想要用循环也不是不行,就是需要加条件判断i和j的边界,有点麻烦

(2)当遇到不相等的时候,就需要回退j,利用next数组来回退,这个过程就需要循环while

遍历的终止条件就是看模式串的指针j有没有遍历到模式串尾部

for(int i=0;i<haystack.length()&&j<needle.length();i++){//i是一直往前运动的while(j>0&&haystack.charAt(i)!=needle.charAt(j)){j=next[j-1];}if(haystack.charAt(i)==needle.charAt(j)){j++;}if(j==needle.length()){//终止条件return i-needle.length()+1;}}

5、Repeated Substring Pattern 重复的子字符串

Given a string s, check if it can be constructed by taking a substring of it and appending multiple copies of the substring together.

Example 1:

Input: s = "abab"
Output: true
Explanation: It is the substring "ab" twice.

Example 2:

Input: s = "aba"
Output: false

Example 3:

Input: s = "abcabcabcabc"
Output: true
Explanation: It is the substring "abc" four times or the substring "abcabc" twice.

Constraints:

  • 1 <= s.length <= 104
  • s consists of lowercase English letters
class Solution {public boolean repeatedSubstringPattern(String s) {int[] next=new int[s.length()];//KMP算法,先求出next数组int j=0;next[0]=0;for(int i=1;i<s.length();i++){while(j>0&&s.charAt(i)!=s.charAt(j)){j=next[j-1];}if(s.charAt(i)==s.charAt(j))j++;next[i]=j;}//假如字符串s由a个重复的子字符串x组成,那么最长相等前后缀肯定是(a-1)个x     xxxxxx//所以字符串s的长度减去最长相等前后缀,剩下的就是重复字符串x的长度//只需要判断字符串s的长度是不是x长度的倍数就可以了,满足就为trueif(next[s.length()-1]==0) return false;//这里注意,如果最长前后缀为0直接返回falseint smallStrlen=s.length()-next[s.length()-1];if(s.length()%smallStrlen==0){return true;}return false;}
}

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

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

相关文章

数据结构与算法实验6——队的应用

一、实验目的 队列的应用&#xff0c;结合应用实例&#xff0c;深入理解和掌握队列。 二、实验软硬件要求 1、VC 6.0 三、实验预习 队列基本操作 四、实验内容&#xff08;实验步骤、测试数据等&#xff09; 1、队列基本操作。请选择循环队列结构或链式队列结构实现队列…

nginx | nginx反向代理/负载均衡/缓存

文章目录 一、Nginx 反向代理1.1 nginx 文件结构1.2 默认的nginx配置文件1.3 实践中的 nginx.conf 二、Nginx 负载均衡2.1 热备负载均衡2.2 轮询负责均衡2.3 加权轮询负载规则2.4 ip_hash 负载均衡2.5 对特定资源实现负载均衡2.6 对不同域名实现负载均衡2.7 实现带有URL重写的负…

Java NIO是New IO还是Non-blocking IO

文章目录 前言NIO到底叫啥通过对比理解NIO传统IO网络编程NIO引入的新概念NIO网络编程两者区别NIO的事件驱动 总结 前言 很多小伙伴对Java NIO的一些概念和编程不是很理解&#xff0c;希望通过本文对Java NIO与传统IO的对比&#xff0c;可以帮助大家更好地理解和掌握Java NIO。…

从学习海底捞到学习巴奴,中国餐饮带洋快餐重归“产品主义”

俗话说“民以食为天”&#xff0c;吃饭一向是国人的头等大事&#xff0c;餐饮业也是经济的强劲助推力。新世纪以来&#xff0c;餐饮业不断讲述着热辣滚烫的商业故事。 2006年&#xff0c;拥有“必胜客”、“肯德基”等品牌的餐饮巨头百胜集团&#xff0c;组织两百多名区域经理…

【洛谷】P9240 [蓝桥杯 2023 省 B] 冶炼金属

题目链接 P9240 [蓝桥杯 2023 省 B] 冶炼金属 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路 这道题可以用数学的方法去做&#xff0c;但是我想不到&#x1f607;有兴趣的可以去看看数学的题解 比较简单的思路就是二分查找&#xff0c;轻松简单不费脑&#xff0c;带你…

Claude 3 on Amazon Bedrock 结合多智能体助力 Altrubook AI 定义消费者 AI 新范式

关于 Altrubook AI 智能消费决策机器人 Altrubook 是全球首创场景化智能决策机器人&#xff0c;由国内外大厂等前员工共同研发&#xff0c;具有定制化 IP 决策机器人、沉浸式购物体验和需求匹配优化等独特优势。目前&#xff0c;Altrubook AI 已完成与 Claude 3 on Amazon Bedr…

STM32H5 读取温度传感器校准值时进 HardFault 的原因分析

1.前言 有客户反馈&#xff0c;在使用 STM32H5 读取温度传感器校准值地址时&#xff0c;会进入 HardFault&#xff0c;而在其他系列芯片中读取这个参数时并没有此现象。在 NUCLEO-H563ZI 开发板上去复现此问题&#xff0c;发现只有开启 ICACHE 后才会复现&#xff0c;初步验证…

ZCMU操作系统课程实验 - 实验1-Linux的使用

登录 1. 打开这个东西 2. 在 文件 - > 打开 中打卡机房里VMOS文件里的这个东东 3. 然后依次操作下去好了&#xff0c;有红色的选项&#xff0c;我都是选的"Do nothing"。完成后就会出现这样一个黑框框。 4. 让你登录。输入&#xff1a;root。密码&…

正则表达式浅析

正则表达式&#xff0c;又称正规表示法、常规表示法&#xff08;英语&#xff1a;Regular Expression&#xff0c;在代码中常简写为regex、regexp或RE&#xff09;&#xff0c;计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很…

【技巧】如何解除Excel“打开密码”?

给Excel表格设置“打开密码”&#xff0c;可以保护表格不被他人随意打开&#xff0c;那如果后续不需要保护了&#xff0c;不想每次打开Excel都需要输密码&#xff0c;要怎么去除“打开密码”呢&#xff1f; 今天分享3个方法&#xff0c;最后一个方法记得收藏起来&#xff0c;以…

有哪些绝美的古诗词呀?

编辑搜图 请点击输入图片描述&#xff08;最多18字&#xff09; 绝美的古诗词是中国古代文化的重要组成部分&#xff0c;它们以优美的语言和深邃的意境&#xff0c;展现了古代人们的生活、情感和思想。以下是一些绝美的古诗词&#xff0c;它们不仅具有文学价值&#xff0c;更…

微功耗轨至轨运算放大器芯片D8541和D8542对比分析

D8541和D8542是芯谷科技推出的两款微功耗轨至轨运算放大器芯片&#xff0c;其中D8541为单运放&#xff0c;D8542为双运放&#xff0c;它特别适用于NTC温度采集电路、ADC基准电压电路、有源滤波器、电压跟随器、信号放大器等电路应用&#xff0c;在新能源充电桩、智能充电枪、储…