代码随想录Day8
题目列表
- 344.反转字符串(LeetCode)
- 541.反转字符串II(LeetCode)
- 卡码网:54.替换数字
解题过程
344.反转字符串
题目描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
提示:
1 <= s.length <= 105
s[i] 都是 ASCII 码表中的可打印字符
解题思路
因为要求原地修改,数组又是连续存放的,可以想到直接让对应位置的数字进行交换,也就是匆匆头尾开始交换一直到中间。
代码展示
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while(left < right){
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
}
541.反转字符串II
题目描述
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
提示:
1 <= s.length <= 104
s 仅由小写英文组成
1 <= k <= 104
解题思路
这相当于自定义一种反转规则。
这道题有一个前提条件:每次要计数2k个;
反转主要有两种规则:看从本次计数起始的位置看是否够 k 个,如果有则反转这k个数,如果不够,则直接反转剩下的数。
注意事项
判断条件
if(i + k <= ch.length),这里的判断条件意味着剩余字符大于或等于 k 个,在这种情况下,就可以反转前 k 个。
代码展示
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for(int i = 0; i < ch.length; i += k*2){
if(i + k <= ch.length){
reverse(ch, i, i + k - 1);
}else{
reverse(ch, i, ch.length - 1);
}
}
return new String(ch);
}
public void reverse(char[] ch, int l, int r){
for(; l < r; l++,r--){
char temp = ch[l];
ch[l] = ch[r];
ch[r] = temp;
}
}
}
卡码网:54.替换数字
题目描述
题目描述
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。
输入描述
输入一个字符串 s,s 仅包含小写字母和数字字符。
输出描述
打印一个新的字符串,其中每个数字字符都被替换为了number
输入示例
a1b2c3
输出示例
anumberbnumbercnumber
提示信息
数据范围:
1 <= s.length < 10000。
解题思路
第一想法是使用可变字符串的 append() 方法。
但看题解这道题意在练习双指针的使用。
双指针解法:
- 首先要根据原字符串中的数字的个数算出新字符串的长度,“number”比 0 - 9 多了五个字符。
- 然后根据新的长度先 new 一个字符数组,然后把原字符串先放到字符数组里。
- 接下来在字符数组上使用双指针,一个指针 old 指向原字符串对应的末尾字符,一个指针 new 指向字符数组的最后一位,准备从最后一位开始填充新数组。
- 如果 old 指向是字母,那就把字母填到 old 指的位置;如果 old 指向是数字,那 new 指向位置就把“number” 倒着填进去,边填充边移动。
- 填充完之后 new 移动到下一个位置,等待 old 向前一位进行新的判断,直到 old 移动到 0 。
注意事项
String 是不可变字符串
代码展示
//双指针写法
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
int originalLength = s.length();
int count = 0;
for (int i = 0; i < originalLength; i++) {
if (Character.isDigit(s.charAt(i))) {
count++;
}
}
int newLength = originalLength + count * 5;
char[] ch = new char[newLength];
int newIndex = newLength - 1;
for (int oldIndex = originalLength - 1; oldIndex >= 0; oldIndex--) {
char c = s.charAt(oldIndex);
if (Character.isDigit(c)) {
ch[newIndex--] = 'r';
ch[newIndex--] = 'e';
ch[newIndex--] = 'b';
ch[newIndex--] = 'm';
ch[newIndex--] = 'u';
ch[newIndex--] = 'n';
} else {
ch[newIndex--] = c;
}
}
System.out.println(new String(ch));
}
}
//直接使用StringBuilder
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
char[] ch = s.toCharArray();
StringBuilder newS = new StringBuilder();
for(char c : ch){
if(Character.isDigit(c)){
newS.append("number");
}else{
newS.append(c);
}
}
System.out.println(newS);
}
}