代码随想录算法训练营day8 | 344.反转字符串 、 541. 反转字符串II、 剑指Offer 05.替换空格 、 151.翻转字符串里的单词 、 剑指Offer58-II.左旋转字符串

学习时间:

  • 晚上 7 点—晚上9点

344.反转字符串:

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

思路

反转字符串依然是使用双指针的方法,只不过对于字符串的反转,其实要比链表简单一些。

因为字符串也是一种数组,所以元素在内存中是连续分布,这就决定了反转链表和反转字符串方式上还是有所差异的。

代码实现

    var reverseString = function (char) {
      let charLen = Math.floor(char.length / 2)
      for (let i = 0, j = char.length - 1; i < charLen; i++, j--) {
        tempStr = char[i];
        char[i] = char[j];
        char[j] = tempStr;
      }
      return char
    }

 541. 反转字符串II

题目链接/文章讲解/视频讲解

思路

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

因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。

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

代码实现:

 var reverse = function (char, start, end) {
      for (let i = start, j = end; i < j; i++, j--) {
        console.log(char[i], char[j])
        tempStr = char[i];
        char[i] = char[j];
        char[j] = tempStr;
      }
      return char
    }
    var reverseStr = function (s, k) {
      let resArr = s.split("");
      for (let i = 0; i < s.length; i += (2 * k)) {
        let l = i, r = i + k - 1 > s.length ? s.length : i + k - 1
        console.log(r, '==')
        reverse(resArr, l, r)
        // console.log(resArr)
      }
      return resArr.join("");
    }

剑指Offer 05.替换空格 

题目链接/文章讲解/视频讲解

思路:

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

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

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

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

代码实现:

  var replaceSpace = function (s) {
      const strArr = Array.from(s)
      let count = 0
      for (let i = 0; i < s.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.翻转字符串里的单词 

题目链接/文章讲解/视频讲解

思路:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转

代码实现:

//先将字符串转换成字符串数组 然后清掉多余空格 再将整个数组转过来 然后再进行每个单词的翻转
    var reverseWords = function (s) {
      const strArr = Array.from(s)
      console.log(strArr.length)
      let slow = 0;
      removeExtraSpace(strArr)
      reverse(strArr, 0, strArr.length - 1)
      console.log(strArr)
      let start = 0
      for (let fast = 0; fast <= strArr.length; fast++) {
        //如果碰到空格了或者fast的长度到达最长的时候就进行翻转单词
        if (strArr[fast] === ' ' || fast === strArr.length) {
          reverse(strArr, start, fast - 1)
          console.log(strArr, fast)
          //翻转成功后 start从fast的下一位开始
          start = fast + 1
        }
      }
      return strArr.join('');
    };
    console.log(reverseWords('the sky is blue'))
    function removeExtraSpace (strArr) {
      let slowIndex = 0;
      let fastIndex = 0;
      while (fastIndex < strArr.length) {
        if (strArr[fastIndex] === ' ' && (fastIndex === 0 || strArr[fastIndex - 1] === ' ')) {
          fastIndex++
        } else {
          strArr[slowIndex++] = strArr[fastIndex++]
        }
      }
      strArr.length = strArr[slowIndex - 1] === ' ' ? slowIndex - 1 : slowIndex
    }
    function reverse (strArr, start, end) {
      let left = start
      let right = end
      while (left < right) {
        [strArr[left], strArr[right]] = [strArr[right], strArr[left]]
        left++
        right--
      }
    }

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

题目链接/文章讲解/视频讲解

思路:

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

代码实现:

var reverseLeftWords = function (s, n) {
      let strArr = Array.from(s)
      let strLen = strArr.length
      reverse(strArr, 0, n - 1)
      reverse(strArr, n, strLen)
      reverse(strArr, 0, strLen)


      return strArr.join('')
    };
    console.log(reverseLeftWords("abcdefg", 2))
    function reverse (strArr, start, end) {
      let left = start
      let right = end
      while (left < right) {
        [strArr[left], strArr[right]] = [strArr[right], strArr[left]]
        left++
        right--
      }
    }


总结

第一次接触完全想不到这么多办法,看来这方面的题必须要多次复习, 希望早日形成自己的题感

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值