代码随想录算法训练营第八天| 344.反转字符串、541. 反转字符串II、剑指Offer 05.替换空格、151.翻转字符串里的单词、剑指Offer58-II.左旋转字符串
反转字符串
题目:344.反转字符串
题目链接:https://leetcode.cn/problems/4sum-ii/
文章讲解:https://programmercarl.com/0344.%E5%8F%8D%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2.html
视频讲解:https://www.bilibili.com/video/BV1fV4y17748/
状态:AC
自己看到题目的第一想法
for循环遍历数组,首位交换,遍历的长度为length/2。
看完代码随想录之后的想法
代码随想录使用双指针的方法做交换更加的便捷。
自己实现过程中遇到哪些困难
无
反转字符串II
541. 反转字符串II
题目链接:https://leetcode.cn/problems/reverse-string-ii/
文章讲解:https://programmercarl.com/0541.%E5%8F%8D%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2II.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频讲解:https://www.bilibili.com/video/BV1dT411j7NN/
状态:写中
自己看到题目的第一想法
for循环每次用2k去增加,每次取其中k个元素做反转。反转的逻辑使用数组的index交换去做逻辑处理。搞了半天把自己给写晕了。特别是处理完2k循环后还需要互换剩余的节点的逻辑。
看完代码随想录之后的想法
反转的逻辑如果使用两个指针的话会简单很多,left和right交换,交换完两个指针移动。然后每次判断right的位置就可以直接用起始位置加k和length进行比较。
int start = i;
//这里是判断尾数够不够k个来取决end指针的位置
int end = Math.min(ch.length - 1, start + k - 1);
自己实现过程中遇到哪些困难
自己写代码写晕了,这种交换的话使用双指针法非常舒服,逻辑也清晰,后续需要记住这个方式。
替换空格
题目: 剑指Offer 05.替换空格
题目链接:https://leetcode.cn/problems/3sum/
文章讲解:https://programmercarl.com/0015.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.html
视频讲解:https://www.bilibili.com/video/BV1Md4y1Q7Yh/
状态:AC
自己看到题目的第一想法
遍历字符串,匹配到后替换。从StringBuilder存储遍历后新的字符串
看完代码随想录之后的想法
代码随想录使用双指针的手法,先将遍历数组,拿到空格数量后将数组扩容到将空格转为%20的长度。然后通过双指针法从最后一个字符的节点和最后一个位置的节点移动位置改变值,将最后一个字符移动到的节点赋值给最后一个位置的节点。赋值完毕后两个节点都往前挪。
自己实现过程中遇到哪些困难
第一次提交没有ac,因为char的判断要使用==
进行判断,使用equals比较执行报错。后面把char转成了String比较就没问题了。
翻转字符串里的单词
题目:151.翻转字符串里的单词
题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/
文章讲解:https://programmercarl.com/0151.%E7%BF%BB%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%87%8C%E7%9A%84%E5%8D%95%E8%AF%8D.html
视频讲解:https://www.bilibili.com/video/BV1uT41177fX/
状态:
自己看到题目的第一想法
双指针法交换,将大字符串切割,构建字符串数组,再使用双指针交换法交换
看完代码随想录之后的想法
整体思路不一样,代码随想录的逻辑是:
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
完成翻转。整体时间复杂度O(n),空间复杂度O(1)或O(n),取决于语言中字符串是否可变
自己实现过程中遇到哪些困难
按照视频所说的将代码AC了,这里出现的一个小点就是a,b,left,right,这4个索引,在判断b去重的时候需要用b > a+1作为判断的条件。因为当出现[2,2,2,2,2]时,如果不用b > a+1作为判断条件的话,b发现b的前面就是2,那就直接return返回空了。
翻转字符串里的单词
题目:JZ58 左旋转字符串
题目链接:https://www.nowcoder.com/practice/12d959b108cb42b1ab72cef4d36af5ec?tpId=13&tqId=11196&ru=/exam/oj
文章讲解:https://programmercarl.com/%E5%89%91%E6%8C%87Offer58-II.%E5%B7%A6%E6%97%8B%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2.html
视频讲解:
状态:
自己看到题目的第一想法
将字符串构建为环形链表 ,通过环形链表的位置和数组的长度构建新的字符串。
看完代码随想录之后的想法
代码随想录的核心还是不能申请额外空间,只能在本串上操作,难度更大一些。
具体步骤为:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
class Solution {
public String reverseLeftWords(String s, int n) {
int len=s.length();
StringBuilder sb=new StringBuilder(s);
reverseString(sb,0,n-1);
reverseString(sb,n,len-1);
return sb.reverse().toString();
}
public void reverseString(StringBuilder sb, int start, int end) {
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}
}
自己实现过程中遇到哪些困难
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param str string字符串
* @param n int整型
* @return string字符串
*/
public String LeftRotateString (String str, int n) {
// write code here
if(str.length() == 0){
return str;
}
if(n == 0){
return str;
}
// 循环左移的意思为字符在一个环形链表里移动,可以用一个指针指向字符起点,然后往后移动n位
ListNode head = null;
ListNode pre = null;
for(int i = 0; i < str.length(); i++){
ListNode cur = new ListNode();
cur.str = String.valueOf(str.charAt(i));
if(i == 0){
head = cur;
pre = head;
}else{
pre.next = cur;
pre = cur;
if(i == str.length() - 1){
cur.next = head;
}
}
}
while(n > 0){
head = head.next;
n--;
}
StringBuilder sb = new StringBuilder();
Integer strLength = str.length();
while(strLength > 0){
sb.append(head.str);
head = head.next;
strLength--;
}
return sb.toString();
}
class ListNode {
public ListNode next;
public String str;
}
}
今日收获&学习时长
收获:
这几题做下来基本上都多用了一些空间,没有达到代码随想录上说的用原空间的要求。
这几道题学习到了反转字符串可以用双指针法,反转字符串有条件且有一段一段规律时,要在for循环的表达式上做文章。
最后再翻转字符串里的单词里学习到了先整体反转再局部反转的方法。
学习时长:
2h,学习加上写文章记录,还是挺耗费精力的。