提示:努力生活,开心、快乐的一天
文章目录
344.反转字符串
💡解题思路
- 采用
双指针
,前后两个指针,一个指向最前面
,一个指向最后面
,两个指针数值翻转后,两个指针再向内移动
🤔遇到的问题
- 移动时忘记移动后面的指针了
💻代码实现
双指针
var reverseString = function (s) {
//双指针,一个指向数组头,一个指向数组尾
let len = s.length
//i与j同步移动,所以此处限制条件可以只限制i
for (let i = 0, j = len - 1; i < len / 2; i++, j--) {
//两个数反转
[s[i], s[j]] = [s[j], s[i]]
}
};
🎯题目总结
- 对于字符串,我们定义两个指针(也可以说是索引下标),
一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素
。 - 如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数;如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,可以考虑使用库函数。
541. 反转字符串II
💡解题思路
- 首先确认需要翻转的数组,翻转过程与前面的翻转字符串基本一致
- 数组的遍历,
i 每次移动 2 * k
,会更加的高效
🤔遇到的问题
- 在翻转数组的时候,没有对数组进行循环,只把头尾的两个数进行了翻转
💻代码实现
遍历+双指针
var reverseStr = function (s, k) {
let resArr = s.split('');
let len = s.length
//在遍历字符串的过程中,i 每次移动 2 * k 就可以
for (let i = 0; i < len; i += 2 * k) {
//翻转字符串中使用双指针
let l = i;
let r = i + k - 1 > len ? len : i + k - 1
//将数组中的数进行翻转
//一前一后俩俩翻转,左右指针移动
while (l < r) {
[resArr[l], resArr[r]] = [resArr[r], resArr[l]]
l++;
r--;
}
}
return resArr.join("")
};
🎯题目总结
遍历的时候,不一定i++去循环、也需要根据题目进行变通,就比如该题,需要i+=2*k。
数组翻转需要循环着,另外后面的指针需要往后移动一位-1
剑指Offer 05.替换空格
💡解题思路
- 确认字符串中空格的个数
扩充数组
,扩充的个数是空格填入的%20后的个数,新数组长度为strArr.length+count*2
双指针
协助进行空格的填充
主要为,left(前指针)原数组的末端
;right(后指针)新数组的末端
;当strArr[left]为空格时,right向前移动三个位置,并分别填入02%,如果不为空格,将left的值赋给right
🤔遇到的问题
- right指向新数组的末端判断错了
💻代码实现
双指针
var replaceSpace = function(s) {
let strArr = Array.from(s)
let len = strArr.length
//统计字符串中,空格的个数
count=0
for(let i =0;i<len;i++){
if(strArr[i]===' '){
count++
}
}
//扩充数组到每个空格替换成"%20"之后的大小
//left指向旧数组的末端
//right指向新数组的末端
let left = len-1
let right = len + count * 2 - 1
//判断left是否为空,引导right向前移动
while(left>=0){
if(strArr[left]===' '){
strArr[right--] = '0';
strArr[right--] = '2';
strArr[right--] = '%';
left--
} else {
//不为空时,将前面指针的数据,给到后面指针
strArr[right--] = strArr[left--]
}
}
return strArr.join('')
};
🎯题目总结
为什么要从后向前填充,从前向后填充不行么?
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
151.翻转字符串里的单词
💡解题思路
- 可先转化为数组
去除多余空格
:字符串头部空格、字符串尾部空格、字符串中两个连着的空格,采用快慢指针,一个方向移动整体翻转字符串
,采用左右指针,对向移动翻转字符串中的每个单词
,通过判断空格的方式,确定一个可翻转的单词
🤔遇到的问题
- 数组去重的条件没有弄清楚
- 忘记移除尾部的空格
- 翻转时候,左右指针对向移动,一个++,一个–
💻代码实现
快慢双指针+前后双指针
var reverseWords = function (s) {
let strArr = Array.from(s)
//去除多余空格
removeExtraSpaces(strArr)
//第一次翻转,整个数组翻转
reverse(strArr, 0, strArr.length - 1)
//第二次翻转,每个单词翻转
//每个单词的起始位置
let start = 0
for (let i = 0; i <= strArr.length; i++){
//i遇到空格,一个单词从star到i-1处
if (strArr[i] === ' ' || i === strArr.length) {
reverse(strArr, start, i - 1)
//修改下一个单词的起始位置
start = i+1
}
}
return strArr.join('');
};
//数组去重
let removeExtraSpaces = function (strArr) {
//快慢两个指针,快指针指向有意义的值,慢指针指向需要更替的值
let len = strArr.length;
let fast = 0
let slow = 0
while (fast < len) {
//移除首位空格
//移除中间2个空格的情况
if (strArr[fast] === ' ' && (fast === 0 || strArr[fast - 1] === ' ')) {
fast++
} else {
strArr[slow] = strArr[fast]
fast++
slow++
}
}
//移除最后一个空格
strArr.length = strArr[slow - 1] === ' ' ? slow - 1 : slow
}
//数组翻转
//start:翻转的起始位置
//end:翻转的结束位置
let reverse = function (strArr, start, end) {
//双指针翻转
let left = start
let right = end
while (left < right) {
//交换
[strArr[left], strArr[right]] = [strArr[right], strArr[left]]
left++
right--
}
}
🎯题目总结
解题思路了解清楚,各种边界的处理
移除多余空格
将整个字符串反转
将每个单词反转
剑指Offer58-II.左旋转字符串
💡解题思路
将整个字符串进行反转
N的位置发生了变化
将N之前的部分进行反转
将N之后的部分进行反转
🤔遇到的问题
- 整体翻转后,N发生了变化,再进行后面的反转时,N的位置找错啦
💻代码实现
双指针
var reverseLeftWords = function(s, n) {
strArr = Array.from(s)
let len = strArr.length
//翻转整个字符串
reverse(strArr, 0, len - 1)
//翻转后的字符串,n变成了从后向前数
//翻转后,前面一部分的字符串
reverse(strArr, 0, len - n - 1)
//翻转后,后面一部分的字符串
reverse(strArr,len-n,len-1)
return strArr.join('')
};
let reverse = function (strArr, start, end) {
//双指针翻转
let left = start
let right = end
while (left < right) {
//交换
[strArr[left], strArr[right]] = [strArr[right], strArr[left]]
left++
right--
}
}
🎯题目总结
反转、反转再反转,也可以用slice函数
进行解题,特殊注意:整体翻转后的N的值域原本的不同了
🎈今日心得
今天的题中,主攻各种反转:
- 在344.反转字符串 (opens new window),第一次讲到反转一个字符串应该怎么做,使用了双指针法。
- . 反转字符串II (opens new window),这里开始给反转加上了一些条件,当需要固定规律一段一段去处理字符串的时候,要想想在for循环的表达式上做做文章。
- 后来在151.翻转字符串里的单词 (opens new window)中,要对一句话里的单词顺序进行反转,发现先整体反转再局部反转 是一个很妙的思路。
- 最后剑指Offer58-II.左旋转字符串,该题则是先局部反转再 整体反转,与151.翻转字符串里的单词 (opens new window)类似,但是也是一种新的思路。