剑指offer5-字符串
Posted lyeeer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer5-字符串相关的知识,希望对你有一定的参考价值。
题目
将一个字符串中的空格替换成 "%20"。
思路
1.首先最容易想到的当然是新建一个字符串,从前往后,如果碰到一个空格,那么就添加在新字符串中添加"%20";如果碰到正常字符,就存入正常字符。(这是如果题目中允许创建新的字符串的情况)
2.(如果不允许新建字符串,而是要求在原来的字符串上进行替换,但是保证输入的字符串后面有足够多的空余内存)那么最简单的方法就是从前往后,碰到空格字符的时候进行替换,由于是把1个字符替换为3个字符串,因此还需要先把后面的字符串往后移两位,再进行插入。但是这样的话,对于每个空格,都会将空格后面的O(n)字符往后移动一次,因此对于含有O(n)个空格字符的字符串,时间复杂度为O(n^2)。
3.这类问题最理想的解答应该是从后往前进行替换。由于遍历一遍字符串,就可以统计出空格的个数,从而得到原字符串再替换后增加的字符数。设置两个指针,分别P1指向原始字符串的末尾,和P2指向替换后字符串的末尾,P1向前移动将字符复制到P2指针的位置,从而P2也向前移动,如果替换到空格,那么就在P2处添加"%20",P2指针同时继续向前移动(注意逆序)。
解法
public static void replaceSpace(StringBuffer str) { int P1=str.length()-1; for(int i=0; i<=P1;i++) { if(str.charAt(i)==‘ ‘) { str.append(" "); } } int P2=str.length()-1; while(P1>=0 && P2>P1) { char c=str.charAt(P1--); if(c==‘ ‘) { str.setCharAt(P2--, ‘0‘); str.setCharAt(P2--, ‘2‘); str.setCharAt(P2--, ‘%‘); } else { str.setCharAt(P2--, c); } } System.out.print(str); }
题目
有两个排序的数组A1和A2,内存在A1的末尾有足够的空余空间容纳A2。请写一个函数,把A2的所有数字插入A1中,并且所有的数字是排序的。
思路
借鉴上题的思路,本题就应该从后往前,由于是有序排列的数组,那么不断比较数组的最后一位数字,将更大的数字其往数组A1的最后位置(数组A1的长度为num1和num2的长度之和)添加。
需要注意的是,两个数组长度不一致,记得要处理剩余部分。当某一个数组未添加到新序列的部分为0时,说明这个数组已经添加完,那么直接将另一个数组未添加的部分添加即可。
解法
public static void replaceSpace2(int[] num1, int[] num2, int length1, int length2) { //int len1=num1.length-1; //int len2=num2.length-1; int len1=length1-1; int len2=length2-1; int mergeLen=length1+length2-1; while(len1>=0 && len2>=0) { if(num1[len1]>num2[len2]) { num1[mergeLen]=num1[len1]; len1--; mergeLen--; } else if(num1[len1]<num2[len2]) { num1[mergeLen]=num2[len2]; len2--; mergeLen--; } else { num1[mergeLen--]=num1[len1--]; num1[mergeLen--]=num2[len2--]; } } while(len1>=0) { num1[mergeLen--]=num1[len1--]; } while(len2>=0) { num1[mergeLen--]=num2[len2--]; } System.out.print(num1); }
扩展--StringBuffer类和StringBuilder类
String类不可修改,一旦创建String对象,其值就无法改变了(最开始赋值时在常量池中开辟的空间的内容不能被修改)。对字符串进行修改时,需要使用StringBuffer类和StringBuilder类,这两种类的对象能够被多次修改,并且不产生新的未使用对象。
StringBuilder和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。但是由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
常用方法:
//StringBuffer public StringBuffer() //无参构造方法 public StringBuffer(int capacity) //指定容量的字符串缓冲区对象 public StringBuffer(String str) //指定字符串内容的字符串缓冲区对象 public insert(int offset, int i) //将 int 参数的字符串表示形式插入此序列中 public delete(int start, int end) //移除此序列的子字符串中的字符 replace(int start, int end, String str) //使用给定 String 中的字符替换此序列的子字符串中的字符 //与String类中类似的方法 public int capacity() //返回当前容量,理论值 public int length() //返回长度(字符数) ,实际值 char charAt(int index) //返回此序列中指定索引处的 char 值 int indexOf(String str) //返回第一次出现的指定子字符串在该字符串中的索引 void setLength(int newLength) //设置字符序列的长度 String substring(int start)返回一个新的 String,它包含此字符序列当前所包含的字符子序列 void setCharAt(int index, char ch) //将给定索引处的字符设置为 ch String toString() //返回此序列中数据的字符串表示形式
以上是关于剑指offer5-字符串的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段
代码随想录算法训练营第8天 | ● 344.反转字符串 ● 541. 反转字符串II ● 剑指Offer 05.替换空格 ● 151.翻转字符串里的单词 ● 剑指Offer58-II.左旋转字符串