JS刷题第八天| 344.反转字符串 541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串

344.反转字符串

建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数

题目链接/文章讲解/视频讲解:代码随想录

先看文章学习思路:对于字符串,我们定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。

var reverseString = function(s) {
for (let i = 0, j = s.length - 1; i < s.length/2; i++, j--) {
let tmp = s[i];
s[i] = s[j];
s[j] = tmp;
    }
};

541. 反转字符串II

建议:本题又进阶了,自己先去独立做一做,然后在看题解,对代码技巧会有很深的体会。

题目链接/文章讲解/视频讲解:代码随想录

知识点1:

在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。因为要找的也就是每2 * k 区间的起点。

所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。

知识点2:学会js中反转字符串方式

知识点3:判断剩余字符的个数,用三元表达式

var reverseStr = function(s, k) {
     const len = s.length;
    let resArr = s.split(""); 
for(let i=0;i<len; i += (2 * k)){
//i + k > len 剩余字符少于 k 个,则将剩余字符全部反转。
     let l = i - 1, r = i + k > len ? len : i + k;
      while(++l < --r) 
      [resArr[l], resArr[r]] = [resArr[r], resArr[l]];
}
return resArr.join("");
};

剑指Offer 05.替换空格

建议:对于线性数据结构,填充或者删除,后序处理会高效的多。好好体会一下。

题目链接/文章讲解:代码随想录

思路

如果想把这道题目做到极致,就不要只用额外的辅助空间了!

首先扩充数组到每个空格替换成"%20"之后的大小。

然后从后向前替换空格,也就是双指针法,过程如下:

i指向新长度的末尾,j指向旧长度的末尾。

有同学问了,为什么要从后向前填充,从前向后填充不行么?

从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。

其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前先后填充元素要来的 每次添加元素都要将添加元素之后的所有元素向后移动。

知识点:

字符串转化为数组

   // 字符串转为数组
  const strArr = Array.from(s);

数组转化为字符串

  // 数组转字符串
  return strArr.join('');
var replaceSpace = function(s) {
     // 字符串转为数组
const strArr=Array.from(s)
  let count = 0;
  // 计算空格数量
  for(let i = 0; i < strArr.length; i++) {
    if (strArr[i] === ' ') {
      count++;
    }
  }
  let left = strArr.length - 1;
  let right = strArr.length + count * 2 - 1;
while(left>0){
     if (strArr[left] === ' ') {
         strArr[right--] = '0';
      strArr[right--] = '2';
      strArr[right--] = '%';
      left--;
     }else{
   strArr[right--] = strArr[left--];
     }
}
// 数组转字符串
  return strArr.join('');
};

151.翻转字符串里的单词

建议:这道题目基本把 刚刚做过的字符串操作 都覆盖了,不过就算知道解题思路,本题代码并不容易写,要多练一练。

题目链接/文章讲解/视频讲解:代码随想录

提高一下本题的难度:不要使用辅助空间,空间复杂度要求为O(1)。

所以解题思路如下:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转
var reverseWords = function(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
        }
    }
    return str.join('')
};

剑指Offer58-II.左旋转字符串

建议:题解中的解法如果没接触过的话,应该会想不到

题目链接/文章讲解:代码随想录

 不能申请额外空间,只能在本串上操作

这道题目也非常类似,依然可以通过局部反转+整体反转 达到左旋转的目的。

具体步骤为:

  1. 反转区间为前n的子串
  2. 反转区间为n到末尾的子串
  3. 反转整个字符串

最后就可以得到左旋n的目的,而不用定义新的字符串,完全在本串上操作。

 自己根据思路单独写出代码

var reverseLeftWords = function(s, n) {
let length=s.length;
const strArr=Array.from(s)
reverse(strArr,0,n-1)
reverse(strArr,n,length-1)
reverse(strArr,0,length-1)
return strArr.join('')
};
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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值