344.反转字符串:
题目链接:https://leetcode.cn/problems/reverse-string/
var reverseString = function(s) {
let len=s.length
for(let left=0,right=len-1;left<right;++left,--right){
[s[right],s[left]]=[s[left],s[right]]
}
};
第一想法:
我当时其实想着是遍历给定的字符串数组,然后将第一个放到最后,以此类推从后往前放即可。
看完视频之后的想法:
1.利用双指针的方法,在最左边和最右边各定义一个指针,依次往中间靠拢,且将左指针遍历的值赋值给右指针遍历的值即可。
541.反转字符串Ⅱ:
题目链接:https://leetcode.cn/problems/reverse-string-ii/
var reverseStr = function(s, k) {
const n=s.length
const arr=Array.from(s)
for(let i=0;i<n;i+=2*k){
reverse(arr,i,Math.min(i+k,n)-1)
}
return arr.join('')
};
const reverse=(arr,left,right)=>{
while(left<right){
const temp=arr[left]
arr[left]=arr[right]
arr[right]=temp
left++
right--
}
}
主要思想:
1.以2k进行移动,操作前k个数即可
2.针对字符串s从i开始到i+k距离进行反转
3.再进行尾部反转。
注意:
split()将一个字符串分割成字符串数组,用""即每个字符之间都会被分割。
join()返回一个由数组元素组成的字符串。
剑指offer 05.替换空格
题目链接:https://leetcode.cn/problems/ti-huan-kong-ge-lcof/
var replaceSpace = function(s) {
const newArr=Array.from(s) //将字符串s转换为数组
let count=0
// 计算空格的数量
for(let i=0;i<newArr.length;i++){
if(newArr[i] ===' '){
count++
}
}
// 双指针法
// 定义left为扩充前的末尾,right为扩充后的末尾
let left=newArr.length-1
let right=newArr.length+count*2-1
while(left>=0){
if(newArr[left] ===' '){
// 从后往前扩充
newArr[right--]='0'
newArr[right--]='2'
newArr[right--]='%'
left--
}else{
newArr[right--]=newArr[left--]
}
}
// 将数组转换为字符串
return newArr.join('')
};
看完视频所学:
数组填充类问题:
1.扩充数组
2.预先给数组扩充到填充后的大小,然后从后向前操作。
3.采用双指针法,从后往前
注意点:
1.千万不要把空格写成空字符串,这里很容易出错
2.right为扩充后的末尾
let right=newArr.length+count*2-1这里的乘2,意思是将原来的基础上再次增加两个空间(%20占有3个位置)
151.翻转字符串里的单词
题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/
var reverseWords = function(s) {
// 将s转换为数组进行相关操作
const strArr=Array.from(s)
// 移除多余空格
removeExtraSpaces(strArr)
// 翻转
reverse(strArr,0,strArr.length-1) //先整体翻转
let start=0
for(let i=0;i<=strArr.length;i++){
if(strArr[i]===' '||i===strArr.length){
// 翻转单词
reverse(strArr,start,i-1) //局部翻转
start=i+1
}
}
// 将strArr转换成为字符串
return strArr.join('')
};
// 删除多余空格
function removeExtraSpaces(strArr){
// 采用双指针法
let slow=0
let fast=0
while(fast<strArr.length){
// 移除开始位置和重复位置
if(strArr[fast]===' '&&(fast===0||strArr[fast-1]===' ')){
fast++
}else{
strArr[slow++]=strArr[fast++]
}
}
// 移除末尾空格
strArr.length=strArr[slow-1]===' '?slow-1:slow
}
// 翻转从start到end的字符
function reverse(strArr,start,end){
let left=start
let right=end
while(left<right){
// 交换
[strArr[left],strArr[right]]=[strArr[right],strArr[left]]
left++
right--
}
}
看完视频所学:
1.首先空格不确定,我们需要删除多余空格,每个单词之间只保留一个空格,最前面和最后面不能有空格存在
2.先清除多余空格
采用双指针的做法,快指针指向我们想要获取的元素,慢指针指向我们获取到的快指针所指向的新位置
先移动快指针,当快指针在最开头或者快指针所指向我们每个单词(看成整体)的开头,也就是对应的空格位置。就让它不断向右移动,找空格。
否则将慢指针所指向的位置赋值给快指针。直至移动到字符串数组的最末尾。
3.两次翻转
先将整个字符串翻转,再翻转每个单词
也可以先局部翻转每个单词,然后再整体翻转。
这里采用先整体再局部
剑指Offer 58-Ⅱ.左旋转字符串
题目链接:https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
var reverseLeftWords = function(s, n) {
// 将字符串转换为字符串数组
const strArr=Array.from(s)
let length=strArr.length
reverseWord(strArr,0,n-1)
reverseWord(strArr,n,length-1)
reverseWord(strArr,0,length-1)
return strArr.join('')
function reverseWord(strArr,start,end){
let temp
while(start<end){
temp=strArr[start]
strArr[start]=strArr[end]
strArr[end]=temp
start++
end--
}
}
};
看完视频之后的想法:
1.遵循先局部再整体的原则(要求:不定义新的字符串,在原字符串上操作)
2.先翻转前n个、再翻转n到末尾的的字符串、再翻转整体。