代码随想录第七天 | 字符串part01
最近这两天上班回去真的有点晚不想动了,趁着周末有时间赶快补补;😊
344.反转字符串
建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数
题目链接/文章讲解/视频讲解:https://programmercarl.com/0344.反转字符串.html
题目感想:
1.本道题目如果使用Java的库函数直接就能返回反转后的字符串,这里考察我们不使用库函数怎么实现,直接就是双指针分别指向字符串两头,然后互换所指向的元素,然后两个指针向中间靠拢,直至相遇;
2.交换这里可以思考一下如何实现的位运算:
异或特性
•a ^ a = 0(相同数异或结果为0)
•a ^ 0 = a(任何数与0异或不变)
•异或满足交换律和结合律:a ^ b = b ^ a,(a ^ b) ^ c = a ^ (b ^ c)
所以一定要注意两个指针不能指向同一个位置后还进行交换,这会导致该位置变为0;
点击查看代码
class Solution {
public void reverseString(char[] s) {
int l = 0;
int r = s.length - 1;
while (l < r) {
s[l] ^= s[r]; //构造 a ^ b 的结果,并放在 a 中
s[r] ^= s[l]; //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
s[l] ^= s[r]; //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
l++;
r--;
}
}
}
// 第二种方法用temp来交换数值更多人容易理解些
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--;
}
}
}
- 反转字符串II
建议:本题又进阶了,自己先去独立做一做,然后在看题解,对代码技巧会有很深的体会。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0541.反转字符串II.html
题目感想:
1.这破题目真难理解,建议直接看视频的讲解,免得浪费时间;
2.这道题目看似是有三种情况,一种是正常反转前k个,另外两种是剩下的多余k个少于2k个,以及少于k个;实际上只有两种情况,
就是正常反转前k个,还有少于k个全部反转;
3.要注意这里的循环是补长不是1而是2k;
4.要明白的一点是,只要剩下的多余k个直接反转前k个就行,反之直接全部反转;
分为两种情况的代码
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for(int i = 0;i < ch.length;i += 2 * k){
int start = i;
// 判断尾数够不够k个来取决end指针的位置
int end = Math.min(ch.length - 1,start + k - 1);
while(start < end){
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end--;
}
}
return new String(ch);
}
}
简化方法
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for(int i = 0;i < ch.length;i += 2 * k){
int start = i;
// 判断尾数够不够k个来取决end指针的位置
int end = Math.min(ch.length - 1,start + k - 1);
while(start < end){
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end--;
}
}
return new String(ch);
}
}
卡码网:54.替换数字
建议:对于线性数据结构,填充或者删除,后序处理会高效的多。好好体会一下。
题目链接/文章讲解:https://programmercarl.com/kamacoder/0054.替换数字.html
题目感想:
1.这道题目挺有意思的,通过扩建新数组然后将老数组迁移,之后从后往前填充单词,直接覆盖就行,如果我们是从前往后进行填充,那么每次填充都需要将后面的数据进行后移,提高了时间复杂度
点击查看代码
// 为了还原题目本意,先把原数组复制到扩展长度后的新数组,然后不再使用原数组、原地对新数组进行操作。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int len = s.length();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) >= 0 && s.charAt(i) <= '9') {
len += 5;
}
}
char[] ret = new char[len];
for (int i = 0; i < s.length(); i++) {
ret[i] = s.charAt(i);
}
for (int i = s.length() - 1, j = len - 1; i >= 0; i--) {
if ('0' <= ret[i] && ret[i] <= '9') {
ret[j--] = 'r';
ret[j--] = 'e';
ret[j--] = 'b';
ret[j--] = 'm';
ret[j--] = 'u';
ret[j--] = 'n';
} else {
ret[j--] = ret[i];
}
}
System.out.println(ret);
}
}

浙公网安备 33010602011771号