力扣 #344 反转字符串
注意:很明显的题目,直接用双指针来解决
class Solution {
public void reverseString(char[] s) {
int length = s.length;
int left = 0;
int right = length-1;
//剪枝
if(length == 1){
return ;
}
while(right > left){
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left ++;
right --;
}
}
}
力扣 #541 反转字符串Ⅱ
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
int length = s.length();
for(int i = 0; i < length; i+= 2*k){
int start = i;
//判断尾部是否够k个
int end = Math.min(length-1, start + k - 1);
//异或反转的使用,减少一个新的存储空间
while(start < end){
ch[start] ^= ch[end];
ch[end] ^= ch[start];
ch[start] ^= ch[end];
start ++;
end --;
}
}
return new String(ch);
}
}
卡码网 #54 替换数字
注意
其实很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
import java.util.Scanner;
class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuilder sb = new StringBuilder();
//直接创建一个字符串,免得用数组来扩容填充
for(int i = 0; i < s.length(); i++){
if(Character.isDigit(s.charAt(i))){
sb.append("number");
}else{
sb.append(s.charAt(i));
}
}
System.out.println(sb);
}
}
力扣 #151 翻转字符串里的单词
注意:这题花费的时间不少,好好认真地啃下来
class Solution {
public String reverseWords(String s) {
//1、用双指针去除首尾,以及中间多余的空格
char[] ch = s.toCharArray();
ch = removeSpace(ch);
//2、反转整个字符串
int length = ch.length;
reverse(ch , 0 , length-1); //注意:这里right指针是需要减一
//3、反转单词
reverseEachWord(ch);
return new String(ch);
}
public char[] removeSpace(char[] ch){
int slow = 0;
int length = ch.length;
for(int fast = 0; fast < length; fast++ ){
if(ch[fast] != ' '){
if(slow != 0){
ch[slow++] = ' ';
}
//遇到空格或者字符串的末尾,遍历完一个单词
while(fast < length && ch[fast] != ' '){
ch[slow ++] = ch[fast ++];
}
//单词的末尾加上一个空格
//ch[slow++] = ' ';
//注意:不能把加空格放在这里,这样会有尾随空格
}
}
//返回新的数组,相当于c++的resize
char[] newChar = new char[slow];
for(int i = 0; i < slow; i++){
newChar[i] = ch[i];
}
return newChar;
}
public void reverse(char[] ch , int left, int right){
if (right >= ch.length) {
System.out.println("set a wrong right");
return;
}
//利用左右指针来反转字符串,有一个前提是right指针是不会超过字符串的长度
while(left < right){
ch[left] ^= ch[right];
ch[right] ^= ch[left];
ch[left++] ^= ch[right--];
}
}
public void reverseEachWord(char[] ch){
int start = 0;
//这里有等于号是为了让end可以是单词的末尾的后一位,是空格证明遍历完一个单词
for(int end = 0; end <= ch.length; end++){
if(end == ch.length || ch[end] == ' '){
reverse(ch, start, end-1);
start = ++end; //一开始用end++,答案不对,为什么?因为这样是先用后加,而不是加之后的结果
}
}
}
}
卡玛网 #55 右旋转字符串
有两种方法,但是思路大体是一样的
1、先整体反转再局部反转
2、先局部反转再整体反转