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

541. 反转字符串II

541. 反转字符串II
题目描述:给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

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

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

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
 const reverse = (arr,left,right) => {
     while(left<right){
         const _ = arr[right]
         arr[right] = arr[left]
         arr[left] = _
         left++
         right--
     }   
 }
var reverseStr = function(s, k) {
    let len = s.length
    const arr = Array.from(s)
    for(let i =0;i<len;i+=2*k){
        reverse(arr,i,Math.min(i+k,len)-1)
    }
    return arr.join('')
};

剑指Offer 05.替换空格

剑指Offer 05.替换空格
题目描述:计算空格的个数,去扩充arr长度。使用双指针,当遇到空格时进行替换。

/**
 * @param {string} s
 * @return {string}
 */
var replaceSpace = function(s) {
    const strArr = Array.from(s)
    let count = 0
    for(let i = 0;i<strArr.length;i++){
        if(s[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]
            left--
            right--
        }
    }
    return strArr.join('')
    

};

其中left表示原来数组最后一个位置,right为新数组最后一个位置。没遇到空格时把arr[right]的值替换为arr[left]。遇到空格时候再依次替换成%20,移动三次右指针后,左指针再向前遍历。

151.翻转字符串里的单词

151.翻转字符串里的单词
题目描述:给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

解题思路:利用双指针先去除多余空格,再去除尾空格。
利用整体翻转+局部反转的思想。
首先整体翻转,讲单词顺序翻转,再用局部翻转,将单词正确拼写。
遍历到空格时代表找到一个单词,根据left指针跟i的位置能够确定每个单词的范围,对每个单词进行局部翻转。

/**
 * @param {string} s
 * @return {string}
 */
 let reverse = function(arr,start,end) {
     while(start<end){
         let _ = arr[start]
         arr[start] = arr[end]
         arr[end]= _
         start++
         end--
     }
 }
var reverseWords = function(s) {
    let arr = Array.from(s)
    let slow = 0
    let fast = 0
    while(fast<arr.length){
        if(arr[fast] === ' ' && (arr[fast-1]===' ' || fast===0)){
           fast++ 
        }else{
            arr[slow] = arr[fast]
            slow++
            fast++
        }
       
    }
     // 移除末尾空格
    arr.length = arr[slow - 1] === ' ' ? slow - 1 : slow;
    reverse(arr,0,arr.length-1)
    let l = 0
    for(let i = 0;i<=arr.length;i++){
        if(arr[i]==' ' || i==arr.length){
            reverse(arr,l,i-1)
            l=i+1
            

        }
    }
    let res = arr.join('')
    return res
};

需要注意翻转的区间,左闭右闭。

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

剑指Offer58-II.左旋转字符串
题目描述:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
解题思路:同样利用局部翻转+全部翻转。

/**
 * @param {string} s
 * @param {number} n
 * @return {string}
 */
 let reverse = function(arr,start,end){
     while(start<end){
        [arr[start],arr[end]] = [arr[end],arr[start]]
        start++
        end--
     }

 }
var reverseLeftWords = function(s, n) {
    let arr  = Array.from(s)
    reverse(arr,0,n-1)
    reverse(arr,n,arr.length-1)
    reverse(arr,0,arr.length-1)
    return arr.join('')
    



};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值