344.反转字符串

题目链接:

https://leetcode.cn/problems/reverse-string/

题目描述:

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

思路:

不使用库函数,在字符数组中利用双指针将对称位置的字符交换从而达到反转的效果。

代码:

/**
 * @param {character[]} s
 * @return {void} Do not return anything, modify s in-place instead.
 */
var reverseString = function(s) {
    let l = 0
    let r = s.length -1

    while(l < r){
        let tmp = s[l]
        s[l] = s[r]
        s[r] = tmp
        l++
        r--
    }
    return s
};

541.反转字符串Ⅱ

题目链接:

https://leetcode.cn/problems/reverse-string-ii/

题目描述:

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

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

输入:s = "abcdefg", k = 2
输出:"bacdfeg"

思路:

创建一个for循环,每次循环将下标[i,min{i+k-1,n-1}]范围元素反转,i自增2k。

代码:

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
var reverseStr = function(s, k) {
    let arr = s.split('')
    let n = arr.length

    let start,end
    for(let i = 0; i < n; i += 2*k){
        start = i
        end = i + k > n ? n : i + k - 1

        //反转
        while(start < end){
            let tmp = arr[start]
            arr[start] = arr[end]
            arr[end] = tmp
            start++
            end--
        }
    }
    return arr.join('')
};

剑指Offer 05.替换空格

题目链接:

https://leetcode.cn/problems/ti-huan-kong-ge-lcof/

题目描述:

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

输入:s = "We are happy."
输出:"We%20are%20happy."

思路:

为了提升题目难度,不使用库函数也不使用js数组储存不同类型的元素,而是使用双指针求解。先要将字符串变为数组。遍历一遍数组,找出空格数量,一个空格被替换后会使数组长度增加2,扩展数组大小。设置两个指针l和r,分别在原数组末尾索引处和扩展后的数组末尾索引处。将l处的元素复制到r处,l和r同步减少。直到l为空格,此时将r-2,r-1,r分别赋值'%', '2', '0',之后l--,r-=3。不断重复上述过程直到l < 0。

代码:

/**
 * @param {string} s
 * @return {string}
 */
var replaceSpace = function(s) {
    let arr = [...s]
    let oldLen = arr.length
    let count = 0
    for(let i of arr){
        if(i === ' ') count++
    }
    arr.length += count*2
    let newLen = arr.length
    let l = oldLen - 1
    let r = newLen - 1
    while(l >= 0){
        if(arr[l] === ' '){
            arr[r] = '0'
            arr[r-1] = '2'
            arr[r-2] = '%'
            r -= 3
            l--
        }
        else{
            arr[r--] = arr[l--]
        }
    }
    return arr.join('')
};

151.翻转字符串里的单词

题目链接:

https://leetcode.cn/problems/reverse-words-in-a-string/

题目描述:

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

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

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

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

输入:s = "  hello world  "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。

输入:s = "a good   example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

思路:

使用快慢指针前序除去原数组中多余的空格。将字符串反转,再将每个单词反转。

代码:

/**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {
    let arr = [...s]
    let n = arr.length

    //反转函数
    function reverse(start, end){
        while(start < end){
            let tmp = arr[start]
            arr[start] = arr[end]
            arr[end] = tmp
            start++
            end--
        }
    }

    //快慢指针去除多余的空格
    let slow = 0, fast = 0
    while(fast < n){
        if(arr[fast] === ' ' && (fast === 0 || arr[fast-1] === ' ')){
            fast++
        }
        else{
            arr[slow++] = arr[fast++]
        }
    }
    arr.length = arr[slow - 1 ] === ' ' ? slow - 1 : slow
    
    //反转整个数组
    n =arr.length
    reverse(0, n-1)

    //反转每个单词
    let pre = 0
    for(let i = 0; i <= n; i++){
        if(arr[i] === ' ' || i === n){
            reverse(pre, i - 1)
            pre = i + 1
        }
    }

    return arr.join('')
};
//使用库函数写法

/**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {
    return s.trim().split(/\s+/).reverse().join(' ')
};

剑指Offer 58 - Ⅱ.左旋字符串

题目链接:

https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/

题目描述:

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

输入: s = "abcdefg", k = 2
输出: "cdefgab"

思路:

(1)库函数,substring

(2)反转,将前后部分分别反转,再反转整个字符串

代码:

/**
 * @param {string} s
 * @param {number} n
 * @return {string}
 */
var reverseLeftWords = function(s, n) {
    return s.substring(n, s.length) + s.substring(0, n);
};
//反转
/**
 * @param {string} s
 * @param {number} n
 * @return {string}
 */
var reverseLeftWords = function(s, n) {

    function reverse(start, end){
        while(start < end){
            [arr[start++], arr[end--]] = [arr[end], arr[start]]
        }
    }

    let arr = Array.from(s)
    reverse(0, n - 1)
    reverse(n, arr.length)
    reverse(0, arr.length)

    return arr.join('')
};