Day10题目
LeetCode344 反转字符串:不要使用内置方法,自己实现反转
核心思想:使用双指针,依次交换即可
class Solution {
public void reverseString(char[] s) {
// 左指针
int l = 0 ;
// 右指针
int r = s.length-1;
while(l < r){
// 交换的过程
char temp = s[l];
s[l] = s[r];
s[r] = temp;
l ++;
r --;
}
}
}
LeetCode514 反转字符串Ⅱ:每2k个反转前k个
核心思想:没有什么很多的优化,能够成功模拟出来就行了。主要技巧:for循环i一次增加2k个,然后反转i到i+k个就行了,需要特殊判断是否超过字符串大小。(Java的string操作也是挺繁琐的)
class Solution {
public String reverseStr(String s, int k) {
StringBuilder sb = new StringBuilder(s);
// i一次加2k
for(int i = 0 ; i < s.length(); i += 2*k){
// i+k没有超范围
if(i+k < s.length()){
// 反转i到i+k 内的
sb = reverse(sb,i,i+k);
}else{
// 超过了,就反转i到末尾
sb = reverse(sb,i,s.length());
}
}
return sb.toString();
}
// 自定义的一个区间反转方法,包含start,不包含end
public StringBuilder reverse(StringBuilder sb , int start , int end){
String substring = sb.substring(start,end);
StringBuilder reversedSubstring = new StringBuilder(substring).reverse();
sb.replace(start,end,reversedSubstring.toString());
return sb;
}
}
KamaCoder54 替换数字:把数字的部分全部替换成字符串"number"
核心思想:1.可以直接使用replace把其中的0-9都替换掉。2. 可以使用双指针,像之前去除数组的指定元素一样,一个代表新数组的index,一个遍历原字符串。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.next();
String result = replaceDigitsWithNumber(s);
System.out.println(result);
}
public static String replaceDigitsWithNumber(String s) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (Character.isDigit(s.charAt(i))) {
// 计算有多少个数字
count++;
}
}
// 开一个新数组,存放答案
char[] res = new char[s.length() + count * 5];
// 左指针从 原字符串的末尾开始
int left = s.length()-1;
// 右指针从 数组的末尾开始
int right = res.length - 1;
while (left >=0 && left <= right) {
char c = s.charAt(left);
// 如果是数字
if (Character.isDigit(c)) {
// 新数组里面填充number
res[right--] = 'r';
res[right--] = 'e';
res[right--] = 'b';
res[right--] = 'm';
res[right--] = 'u';
res[right--] = 'n';
} else {
// 不是数字则直接添加到新数组
res[right--] = c;
}
// 处理字符串中下一个字符
left--;
}
return new String(res);
}
}
LeetCode151 反转单词:主要是给的字符串中空格数量不一,你需要把前后空格去掉,单词之间只能留一个空格
核心思想:去除多余空格,反转整个字符串,逐一反转每个单词。总之自己能模拟出来就行,我的做法就略有不同。
class Solution {
public String reverseWords(String s) {
// 返回值
StringBuilder res = new StringBuilder();
// 插入的位置
int index = 0;
for(int i = s.length()-1 ; i >= 0 ; i--){
// 如果字符串中这个字符为空
if(s.charAt(i) == ' '){
// 如果返回值中为空,则首部不能有空格,所以直接continue
if(res.isEmpty()){
continue;
// 如果返回值中有值,那么这个空格应该是单词中间的空格,要判断是否已经有一个空格了,单词间只能有一个空格。
}else if(res.charAt(res.length()-1) != ' '){
// 返回值末尾没有一个空格,那么就加上一个空格
res.append(' ');
// 将添加字母的位置移动到返回值末尾
index = res.length();
}
}else{
// 正常插入到index的位置
res.insert(index,s.charAt(i));
}
}
// 因为上面的逻辑在最后一个单词末尾如果有空格也会插入,这里做一下去除空格
return res.toString().trim();
}
}
KamaCoder55 右旋字符串:实际上就是把字符串最后n位移动到字符串开头
核心思想:这题主要要在原地完成。所以使用区间反转完成,先局部反转前length-n
个,然后反转后n
个,最后全部反转就完成
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int index = in.nextInt();
String s = in.next();
// 先全部翻转,然后局部翻转,以 abcde,2 为例
char[] chars = s.toCharArray();
// 反转0 到 length-1-index,就是除了后index个之外的,cbade
reverseString(chars,0,chars.length-index-1);
// 反转最后 index个,cbaed
reverseString(chars,chars.length-index,chars.length-1);
// 全部反转一遍,deabc
reverseString(chars,0,chars.length-1);
System.out.println(new String(chars));
}
// 自定义的反转区间内元素的方法,包含start和end
public static void reverseString(char[] chars, int start, int end) {
while(start<=end){
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
start++;
end -- ;
}
}
}