【代码随想录算法训练营】D8 344. 反转字符串 541. 反转字符串Ⅱ 剑指offer 05. 替换空格 151. 翻转字符串里的单词 剑指offerⅡ. 左旋转字符串

今日题目:

  • 344. 反转字符串
  • 541. 反转字符串Ⅱ
  • 剑指offer 05. 替换空格
  • 151. 翻转字符串里的单词
  • 剑指offerⅡ. 左旋转字符串

解题思想:

  1. 双指针反转字符串

344题反转字符串并不难,要求原地反转,只需要头指针和尾指针元素两两交换,指针向内收缩就好了。
541题最难的点可能是读懂题。。。说人话就是每隔k个元素反转一次字符串。在写for循环的时候,会下意识的i++来控制变量,但是这样会发现进来逻辑处理起来非常麻烦,最优雅的方式是,遍历过程中每趟i += (2*k),然后判断是否有需要反转的区间
所以当需要固定规律一段一段去处理字符串的时候,要想想在for循环的表达式上做文章。
这道题还需要注意的一个地方是,需要先把字符串通过split("")分割成字符串数组,才能正常的进行反转,最后通过join("")将字符串数组变为字符串。

  1. 从后往前的双指针

05替换空格这道题,要求原地改,代码随想录提供的解题思路是先进行一遍字符串遍历,计算出数组空格个数,扩充数组。然后从后往前的双指针,L在数组原始长度末尾,R在数组扩充长度的末尾,L往前探索,如果不为空则把L所在的值赋给R,如果为空则R倒序赋值%20。

  1. 反转单词

第151题,思路就是1、移除多余空格,2、反转整个字符串,3、反转每个单词。移除多余空格就利用快慢指针遍历数组,移除多余空格

  1. 左旋转字符串

这道题要想原地修改的话还是有点难度的(我靠调用库函数做出来了kkk)。跟上一题思路也有点类似:1. 反转区间为签n的子串 2. 反转区间为n到末尾的子串 3.反转整个字符串。思路很妙,没接触过确实比较难想


代码:

  • 344 . 反转字符串
var reverseString = function(s) {
    let L = 0
    let R = s.length-1
    while(L<=R) {
        let temp = s[L]
        s[L] = s[R]
        s[R] = temp
        L++
        R--
    }

    return s
};
  • 541 . 反转字符串Ⅱ
var reverseStr = function(s, k) {
    const len = s.length
    let resArr = s.split("")
    for(let i = 0; i<len; i+= (2*k) ) {
        k = i+k>len ? len-i : k

        reverseFns(resArr, i, i+k-1)
    }

    function reverseFns(arr, start, end) {
        let L = start
        let R = end
        while(L <= R) {
            let temp = arr[R]
            arr[R] = arr[L]
            arr[L] = temp
            L++
            R--
        }
    }

    return  resArr.join("")
};
  • 剑指offer 05. 替换空格
//自己第一次实现用的是数组的splice方法
var replaceSpace = function(s) {
    s=s.split("")
    for(let i =0; i<s.length; i++) {
        if(s[i] == ' ') {
            s.splice(i,1,'%20')
        }
    }

    return s.join("")
};
//代码随想录提供的方法
var replaceSpace = function(s) {
    s=s.split("")  //字符串转数组
    let counter = 0
    s.forEach(item => {
        if(item === ' ') counter++
    }) 

    let L = s.length-1
    let R = s.length + counter*2 -1

    while(L >= 0) {
        if(s[L] === ' ') {
            s[R--] = '0'
            s[R--] = '2'
            s[R--] = '%'
            L--
        } else {
            s[R--] = s[L--]
        }
    }

    return s.join('')
};
  • 151 . 翻转字符串里的单词
/**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {
    s = s.split("")
    let L = R = 0

    //首先去除所有多余空格
    while(R<s.length) {
        if(s[R] == ' ' && (L == 0 || s[R-1] == ' ')){
            R++
        } else {
            s[L++] = s[R++]
        }
        
    }
    // if(s[L-1]== ' ') s = s.slice(0, L-1)  这种做法是错的!因为不管后面的是不是空格,字符串长度都需要重新调整
    s.length = s[L-1] === ' '? L-1: L    //去除末尾空格

    //整体翻转
    reverse(0, s.length-1)
    
    //局部单词翻转
    let start = 0
    for(let i = 0; i<=s.length; i++) {
        if(s[i] == ' ' || i == s.length) {  //注意这里,还要考虑i探索到队尾的情况,不然最后一个单词会漏转
            reverse(start, i-1)
            start = i+1
        }
    }


    //通用reverse函数
    function reverse(start, end) {
        let L = start
        let R = end
        while(L<=R){
            let temp = s[L]
            s[L] = s[R]
            s[R] = temp
            L++
            R--
        }
    }


    return s.join("")
};
  • 剑指offerⅡ. 左旋转字符串
//我的做法
var reverseLeftWords = function(s, n) {
    s=s.split('')
    let count = 0
    while(count<n) {
        let temp = s.shift()
        s.push(temp)
        count++
    }

    return s.join('')
};

//代码随想录给的思路
var reverseLeftWords = function(s, n) {
    s=s.split('')
    reverse(0,n-1)
    reverse(n, s.length-1)
    reverse(0, s.length-1)

    function reverse(start, end) {
        let L = start
        let R = end
        while(L<=R) {
            let temp = s[L]
            s[L] = s[R]
            s[R] = temp
            L++
            R--
        }
    }
    return s.join('')
};

总结:

今天美团实习一面结束,可以开始追进度啦 不过这周还要把开题报告给解决了…先占个坑等明天补叭
在处理字符串的时候,一般先通过str = str.split('')把它转为数组形式,再最后return的时候通过str.join('')转回字符串形式。
这几道题收获还蛮大的,有些思想确实自己做题的话很难想到:对for循环的i变量处理、先局部反转再整体反转的思想…都是值得自己多次熟练练习并掌握的。并且有时候自己太过于依赖库函数的调用,导致时间复杂度上不是很好。practice makes perfect,继续加油吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值