🍅1.进场须知
本章旨在为大家锻炼字符串处理的基础,在大家做题的同时,也该了解自己的语言是否含有相应的库函数,在进阶训练难题时,大家应该直接使用库函数,不然代码会非常冗余。因为进阶难题字符串的处理往往只是做题的一部分,而基础训练只需要对字符串处理。所以大家训练的时候一定也要记住是否有合适的库函数。
🍐2.处理字符,血战力扣
🍍1.反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
题目链接:反转字符串https://leetcode-cn.com/problems/reverse-string/
题目分析:题目的要求非常简单,就是将字符数组反转,但要求在原数组上操作,那我们就不可以new一个新的char[]数组来交换。既然如此,那我们一定要想到利用双指针,一个指向数组头部,一个指向数组尾部,交换值后,同时向内移动继续,直到两个指针相遇。
方法:双指针
时间复杂度O(n):n为数组s的长度,一共进行了N/2次交换,常数1/2舍去,时间复杂度为O(n)
空间复杂度O(1):只用了两个int变量,复杂度为O(1)
class Solution { public void reverseString(char[] s) { //左指针指向头部,右指针指向尾部 int left=0; int right=s.length-1; while(left<right){ //交换值 exch(left,right,s); //两指针同时向中间移动 left++; right--; } } //写一个交换方法 public void exch(int i,int j,char[] s){ char a=s[i]; s[i]=s[j]; s[j]=a; } }
🍠2.反转字符串||
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
题目链接:反转字符串||https://leetcode-cn.com/problems/reverse-string-ii/
题目解析:这道题是第一题的进阶,难点在于要知道合适的反转范围,我们用指针l和指针r来每次找到需要反转的范围。尤其是注意在最后,r是直接在l的基础上+k-1,有可能超出数组长度,所以每次需要在r和n-1之间取小值。这道题l和r的下标,建议画个图理解,不要光靠脑子想象,这是大忌。
方法:双指针
时间复杂度O(n):n为s的长度。
空间复杂度O(1)或O(n):这取决于你的语言,像Java中的String不可变,我们只能用一个char数组取修改,如果你的语言字符串可修改,可在原数组操作即可,这时时间复杂度就是O(1)。
class Solution { public String reverseStr(String s, int k) { char[] arr=s.toCharArray(); int n=arr.length; //l指针每次+2k for(int l=0;l<n;l=l+2*k){ //r每次在l的基础上+k-1(因为找的是下标,建议画个图写出下标理解一下) int r=l+k-1; //如果r超出了数组长度,这时r就比n-1大了,我们只取到n-1即可 reverse(arr,l,Math.min(n-1,r)); } return String.valueOf(arr); } //写一个反转方法,反转char[]数组指定的索引区间 public void reverse(char[] arr,int i,int j){ while(i<j){ char a=arr[i]; arr[i++]=arr[j]; arr[j--]=a; } } }
🍌3.替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
题目链接:替换空格https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/
题目分析:由于是字符串,有些语言的字符串是可修改的,某些语言的字符串是不可修改的,像Java的String是不可修改的。所以这里我们用StringBuilder,当然StringBuffer也可,两者都是可修改的字符串类,但是StringBuilder的效率更高。我们遍历题目给的String,如果不是空格,之间在StringBuilder后加上相同的,如果是空格,就加上%20,最后把StringBuilder转换为String返回即可。
方法: 利用可变字符串(这里也可用字符串数组),遍历相加
时间复杂度O(n):n为字符串的长度,主要是遍历的耗时
空间复杂度O(n):主要是创建了StringBuilder对象,长度最长可能为3n。
class Solution { public String replaceSpace(String s) { StringBuilder arr=new StringBuilder(); for(int i=0;i<s.length();i++){ //是空格就加上%20 if(s.charAt(i)==' '){ arr.append("%20"); }else{ //不是空格就之间加到arr末尾 arr.append(s.charAt(i)); } } //返回String形式 return arr.toString(); } }
🍐4.翻转字符串里的单词(中等)
给你一个字符串 s ,逐个翻转字符串中的所有 单词 。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。
说明:
输入字符串 s 可以在前面、后面或者单词间包含多余的空格。
翻转后单词间应当仅用一个空格分隔。
翻转后的字符串中不应包含额外的空格。
题目链接:翻转字符串里的单词https://leetcode-cn.com/problems/reverse-words-in-a-string/
题目分析:这道题在字符串里算是较有难度的一题,因为它几乎考察了所有的字符串处理操作,想要效率高的完成,还是比较难的,即使是用API,很多人也无从下手,但是这也让我们了解了更多API的使用操作,是一道非常好的题。下面我为大家讲解多种方法以及它们的效率如何。
❗️考点解析:1.如何修剪掉两端空格
2.如何把单词反转过来
3.如何跳过中间连续的空格