Leetcode——字符串

159 阅读2分钟

344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
输入: s = ["h","e","l","l","o"]
输出: ["o","l","l","e","h"]
var reverseString = function(s) {
    const n = s.length;
  	//双指针不断交换left和right位置的元素
    for (let left = 0, right = n - 1; left < right; left++, right--) {
        [s[left], s[right]] = [s[right], s[left]];
    }
};
// 方法2:return s.reverse();

541. 反转字符串 II

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

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

解题思路:分成两步
1. 遍历字符串,以2K的步长进行遍历
2. 每次对[i,i+k-1]的区间进行反转即可

// 反转数组中某个区间
const reverseArr = (arr, left, right) => {
    while (left < right) {
        [arr[left], arr[right]] = [arr[right], arr[left]];
        left++;
        right--;
    }
};

const reverseStr = (s, k) => {
    const arrS = s.split('');
    const len = arrS.length;
    for (let i = 0; i < len; i += 2 * k) {
        // 反转该区间
        reverseArr(arrS, i, i + k - 1);
    }
    return arrS.join('');
};

剑指 Offer 05. 替换空格

请实现一个函数,把字符串 `s` 中的每个空格替换成"%20"
var replaceSpace = function(s) {
    s=s.split(' ').join('%20');
    return s
};

151. 颠倒字符串中的单词

输入: s = "the sky is blue"
输出: "blue is sky the"

首先先根据空格分割s,变成['the','sky','is','blue'],然后从最后开始push进res[],最后join(" ")

var reverseWords = function(s) {
  let arr=s.split(' ')
  let res=[]
  for(let i=arr.length-1;i>=0;i--){
    if(arr[i] == "") continue
    else  {
      res.push(arr[i])
    }
  }
  return res.join(' ')

};

剑指 Offer 58 - II. 左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。
请定义一个函数实现字符串左旋转操作的功能。
比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"
// 方法1:使用额外空间
var reverseLeftWords = function(s, n) {
    let res = []
    res.unshift(s.slice(0,n))
    res.unshift(s.slice(n,s.length))
    return res.join('')
};

方法2:不使用额外空间
把后(len-n)个字母移到最前面
len-1是固定不变的,但是s逐步加一个,正好是从最后一个一直挪知道挪动(len-n)个

var reverseLeftWords = function(s, n) {
  const length = s.length;
  let i = 0;
  while (i < length - n) {
    s = s[length - 1] + s;
    i++;
  }
  return s.slice(0, length);
};

28. 实现 strStr()

给你两个字符串 haystack 和 needle ,
请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回  -1 。

方法1: substring() 方法用于提取字符串中介于两个指定下标之间的字符string.substring(start,stop) substr()方法可在字符串中抽取从 start下标开始的指定数目的字符string.substr(start,length) slice() 方法可提取字符串的某个部分并以新的字符串返回被提取的部分string.slice(start,end)

/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function(haystack, needle) {
    if(haystack === needle){
        return 0;
    }
    const n = needle.length;
    for(let i = 0; i < haystack.length - n + 1; i++){
        if(needle === haystack.substr(i, n)){
            return i;
        }
    }
    return -1;
};

方法2:KMP算法:解决字符串不匹配的问题

IMG_5446.heic

var strStr = function (haystack, needle) {
    if (needle.length === 0)
        return 0;

    const getNext = (needle) => {
        // i表示后缀末尾,j表示前缀末尾
        // i一直往后移动,j来更新next矩阵
        let next = [];
        let j = 0;
        next.push(j);

        for (let i = 1; i < needle.length; i++) {
            while (j > 0 && needle[i] !== needle[j])
            //j不等i于的时候,j会退到前面一个元素下标值
                j = next[j - 1];
            if (needle[i] === needle[j])
                j++;
            next.push(j);
        }

        return next;
    }

    let next = getNext(needle);
    let j = 0;
    // j指向模式串,i指向文本串
    for (let i = 0; i < haystack.length; i++) {
        while (j > 0 && haystack[i] !== needle[j])
            j = next[j - 1];
        if (haystack[i] === needle[j])
            j++;
        if (j === needle.length)
            return (i - needle.length + 1);
    }

    return -1;
};