本篇文章 , 是在代码随想录 60 天编程挑战的基础上进行的题目讲解
参与链接在此 : https://programmercarl.com/other/xunlianying.html
大家好 , 这个专栏 , 给大家带来的是 60 天刷题强训 . 最令大家头疼的事就是刷题了 , 题目又臭又长又抽象 , 有的题读都读不懂 , 更别说做了 . 所以 , 这个专栏想要帮助大家摆脱困境 , 横扫饥饿 , 做回自己 . 让大家掌握最常见的面试题 , 面对陌生的题目也不至于无从下手 .
也希望大家监督 , 60 天从 0 到 1 , 咱们一起做大佬 ~
今天是 Day7 , 大家加油~
专栏链接 : https://blog.csdn.net/m0_53117341/category_12247938.html?spm=1001.2014.3001.5482
昨天的打卡链接 : http://t.csdn.cn/dUWnw
题目链接 : 344. 反转字符串
这道题 , 非常简单 , 同样是双指针的问题
定义 left 指针在最左面 , 定义 right 指针在最后面
然后交换 left 指针和 right 指针对应的元素 , left 往后移动 , right 往前移动
循环条件就是 left < right , 最中间的那个元素是不需要交换的
代码就在这里
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while(left < right) {
char t = s[left];
s[left] = s[right];
s[right] = t;
left++;
right--;
}
}
}
题目链接 : 541. 反转字符串 II
本道题目也是在上一道题的基础上产生的变种 , 来看解析
class Solution {
private static void reverse(char[] chars,int left,int right) {
while(left < right) {
char tmp = chars[left];
chars[left] = chars[right];
chars[right] = tmp;
left++;
right--;
}
}
public String reverseStr(String s, int k) {
// 1. 将字符串转换成数组方便操作
char[] chars = s.toCharArray();
// 2. i 每次走 2K 步
for(int i = 0;i < chars.length;i += 2 * k) {
// 让 left 指向左边
int left = i;
// 让 right 指向 k 位置
// 但是有可能最后一组不够 2K 个元素了,那就把前 k 个元素交换
// 所以需要分类讨论
// right 没走到最后面的时候正常交换
// right 走到最后面不够一组的情况下,直接交换left~数组最后一个元素
int right = Math.min(left + k - 1,chars.length - 1);
// 对 left~right 区间进行交换
reverse(chars,left,right);
}
// 再将结果转换成字符串然后返回
return new String(chars);
}
}
题目链接 : 剑指 Offer 05. 替换空格
这道题 , 我们可以借助 Java 中的 StringBuilder
当遇见普通元素的时候 , 正常拼接即可
当遇见空格的时候 , 我们直接拼接一个 %20 即可
代码如下
class Solution {
public String replaceSpace(String s) {
StringBuilder sb = new StringBuilder();
for(int i = 0;i < s.length();i++) {
if(s.charAt(i) == ' ') {
sb.append("%20");
} else {
sb.append(s.charAt(i));
}
}
return sb.toString();
}
}
题目链接 : 151. 反转字符串中的单词
这道题 , 他是有点东西在的 , 比较麻烦 , 来看栗子
推荐大家去看一下视频讲解 : https://www.bilibili.com/video/BV1uT41177fX/?vd_source=b0e82af8eb60883fa2180dda1770795d
代码在这里~
class Solution {
public String reverseWords(String s) {
// 1. 先转化成数组方便操作
char[] chars = s.toCharArray();
// 2. 去除首尾以及中间多余空格
chars = removeExtraSpaces(chars);
// 3. 反转整个字符串
reverse(chars,0,chars.length-1);
// 4. 反转每个单词
reverseEachWord(chars);
// 5. 返回结果
return new String(chars);
}
// 去除首尾以及中间多余空格
private static char[] removeExtraSpaces(char[] chars) {
// 思路类似于移除元素,把要移除的元素当做空格即可
// 1. 定义快慢指针
int fast = 0;
int slow = 0;
// 快指针负责遍历数组中的每一个元素
// 找到不是空格的元素,把它放在 slow 上
for(;fast < chars.length;fast++) {
// 找到了不是空格的元素
if(chars[fast] != ' ') {
// 注意:slow不是初始位置的时候,我们应该手动提供一个空格加入到答案中
if(slow != 0) {
// slow 记得往后移动
chars[slow++] = ' ';
}
// 将这一个单词加入到slow位置上
while(fast < chars.length && chars[fast] != ' ') {
chars[slow++] = chars[fast++];
}
}
}
// 去掉空格之后数组的长度一定变化了
// 我们直接 new 一个新数组,将目前数组的元素拷贝过来
// 注意:要拷贝 slow 之前的,slow 之前的都是有效元素
char[] newChars = new char[slow];
newChars = Arrays.copyOf(chars,slow);
return newChars;
}
// 反转整个字符串
private static void reverse(char[] chars,int left,int right) {
while(left < right) {
char tmp = chars[left];
chars[left] = chars[right];
chars[right] = tmp;
left++;
right--;
}
}
// 反转每个单词
private static void reverseEachWord(char[] chars) {
// 1. 定义双指针
int start = 0;
int end = 0;
// 2. end 负责找到每一个单词的末尾位置
for(;end <= chars.length;end++) {
// end 走到数组末尾了 || end 找到空格了
if(end == chars.length || chars[end] == ' ') {
// 将 start 位置~end的前一个位置进行反转
reverse(chars,start,end-1);
// 更新新的 start 位置
start = end + 1;
}
}
}
}
题目链接 : 剑指 Offer 58 - II. 左旋转字符串
什么都不多说 , 看图
代码随想录当中的这个图能完全说明问题 , 大家看这个即可
先反转前半部分 , 也就是 0~n-1 部分
再反转后半部分 , 也就是 n~arr.length-1 部分
最后全部翻转
我们惊喜地发现 , 竟然达到了左旋转字符串的效果
class Solution {
public String reverseLeftWords(String s, int n) {
// 1. 将字符串转化成数组
char[] chars = s.toCharArray();
// 2. 反转前半部分
reverse(chars,0,n-1);
// 3. 反转后半部分
reverse(chars,n,chars.length-1);
// 4. 一起反转
reverse(chars,0,chars.length-1);
return new String(chars);
}
private static void reverse(char[] chars,int left,int right) {
while(left < right) {
char tmp = chars[left];
chars[left] = chars[right];
chars[right] = tmp;
left++;
right--;
}
}
}