leetcode-字符串

字符串基础API使用

因为字符串不可以修改

这里增的意思并不是说直接增添内容,而是创建字符串的一个副本,再进行操作

除了常用+以及${}进行字符串拼接之外,还可通过concat

concat

用于将一个或多个字符串拼接成一个新字符串

let stringValue = "hello ";
let result = stringValue.concat("world");
console.log(result); // "hello world"
console.log(stringValue); // "hello"

这里的删的意思并不是说删除原字符串的内容,而是创建字符串的一个副本,再进行操作

常见的有:

  • slice()
  • substr()
  • substring()

这三个方法都返回调用它们的字符串的一个子字符串,而且都接收一或两个参数。

let stringValue = "hello world";
console.log(stringValue.slice(3)); // "lo world"
console.log(stringValue.substring(3)); // "lo world"
console.log(stringValue.substr(3)); // "lo world"
console.log(stringValue.slice(3, 7)); // "lo w"
console.log(stringValue.substring(3,7)); // "lo w"
console.log(stringValue.substr(3, 7)); // "lo worl"

日常主要使用 slice

这里改的意思也不是改变原字符串,而是创建字符串的一个副本,再进行操作

常见的有:

  • trim()
  • repeat()
  • padStart()、padEnd()
  • toLowerCase()、 toUpperCase()

trim()

删除前、后或前后所有空格符,再返回新的字符串

let stringValue = " hello world ";
let trimmedStringValue = stringValue.trim();
console.log(stringValue); // " hello world "
console.log(trimmedStringValue); // "hello world"

repeat()

接收一个整数参数,表示要将字符串复制多少次,然后返回拼接所有副本后的结果

let stringValue = "na ";
let copyResult = stringValue.repeat(2) // na na 

padEnd()

复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件

let stringValue = "foo";
console.log(stringValue.padStart(6)); // " foo"
console.log(stringValue.padStart(9, ".")); // "......foo"

toLowerCase()、 toUpperCase()

大小写转化

let stringValue = "hello world";
console.log(stringValue.toUpperCase()); // "HELLO WORLD"
console.log(stringValue.toLowerCase()); // "hello world"

除了通过索引的方式获取字符串的值,还可通过:

  • chatAt()
  • indexOf()
  • startWith()
  • includes()

charAt()

返回给定索引位置的字符,由传给方法的整数参数指定

let message = "abcde";
console.log(message.charAt(2)); // "c"

indexOf()

从字符串开头去搜索传入的字符串,并返回位置(如果没找到,则返回 -1 )

let stringValue = "hello world";
console.log(stringValue.indexOf("o")); // 4

startWith()、includes()

从字符串中搜索传入的字符串,并返回一个表示是否包含的布尔值

let message = "foobarbaz";
console.log(message.startsWith("foo")); // true
console.log(message.startsWith("bar")); // false
console.log(message.includes("bar")); // true
console.log(message.includes("qux")); // false

转换方法

split

let str = "12+23+34"
let arr = str.split("+") // [12,23,34]

模板匹配方法

针对正则表达式,字符串设计了几个方法:

  • match()
  • search()
  • replace()

match()

接收一个参数,可以是一个正则表达式字符串,也可以是一个RegExp对象,返回数组

let text = "cat, bat, sat, fat";
// 以 at 结尾
let pattern = /.at/;
let matches = text.match(pattern);
console.log(matches[0]); // "cat"

search()

接收一个参数,可以是一个正则表达式字符串,也可以是一个RegExp对象,找到则返回匹配索引,否则返回 -1

let text = "cat, bat, sat, fat";
let pos = text.search(/at/);
console.log(pos); // 1

replace()

接收两个参数,第一个参数为匹配的内容,第二个参数为替换的元素(可用函数)

let text = "cat, bat, sat, fat";
let result = text.replace("at", "ond");
console.log(result); // "cond, bat, sat, fat"

let result2 = text.replace(/.at/g, 'ond');
console.log(result); // 'cond, bond, sond, fond'

leetcode-字符串

反转字符串

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

简单。。

/**
 * @param {character[]} s
 * @return {void} Do not return anything, modify s in-place instead.
 */
var reverseString = function(s) {
    for(let i = 0; i < Math.floor(s.length / 2); i++) {
        let temp = s[i];
        s[i] = s[s.length - i - 1];
        s[s.length - i -1] = temp
    }
    return s
};

反转字符串 ||

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

字符串不好处理,转成数组来解决,这题不难,就是要仔细考虑考虑边界的问题

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

替换空格

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

参考:代码随想录。

简单解法

正则就可以解决

/**
 * @param {string} s
 * @return {string}
 */
var replaceSpace = function(s) {
    return s.replace(/\s/g, '%20')
};

双指针法

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

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

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

替换空格

但 js 的字符串是不可改变的,不可避免要额外的辅助空间,那就更简单了,不需要如下图这么复杂。

翻转字符串里的单词

这题的要求

**进阶:**如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。

显然, js的 字符串是不可变的。

这题就用数组和字符串API解决(先将字符串转换成数组)

/**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {
    return s.split(' ').filter(item => item != '').reverse().join(' ').trim();
};

实现 strStr()

地址:https://leetcode.cn/problems/implement-strstr/

这题简答解决就是直接调用API解决,但这题往深了说是想考KMP算法,KMP思想其实不难,但在实现过程中有很多巧合(这一定有内在的数学联系,不过我理解不了,这能把他当成一种巧合),所以不要去理解它,去感受它。

在寻找这个规律的过程可以看看代码随想录的讲解:https://www.bilibili.com/video/BV1PD4y1o7nd/

JS实现KMP

/**
 * @param {string} haystack
 * @param {string} needle
 * @return {number}
 */
var strStr = function(haystack, needle) {
    if (needle.length === 0)
        return 0;

    const getNext = (needle) => {
        let next = [];
        let j = 0;
        next.push(j);

        for (let i = 1; i < needle.length; i++) {
            while (j > 0 && needle[i] !== needle[j])
                j = next[j - 1];
            if (needle[i] === needle[j])
                j++;
            next.push(j);
        }
        return next;
    }

    let next = getNext(needle);
    let j = 0;
    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;
};

重复的子字符串

地址:https://leetcode.cn/problems/repeated-substring-pattern/

简单解法:调用API,哈哈

/**
 * @param {string} s
 * @return {boolean}
 */
var repeatedSubstringPattern = function(s) {
    for(let i = 0; i < s.length; i++) {
        let str = s;
        let cstr = s.slice(0, i);
        let nstr = s.replaceAll(cstr, '');
        if(nstr == '') {
            return true
        }
    }
    return false
};

深入解法:

凡是遇到字串的问题,都看看是否可以用KMP算法解决,这题也可以用KMP解决。

参考代码随想录:

在这里插入图片描述

很多时候,题目更高效率的解决都是规律的发现,但规律的背后都是数学原理(咱理解不了),所以感受它,不要理解。。。

/**
 * @param {string} s
 * @return {boolean}
 */
var repeatedSubstringPattern = function (s) {
    if (s.length === 0)
        return false;

    const getNext = (s) => {
        let next = [];
        let j = -1;

        next.push(j);

        for (let i = 1; i < s.length; i++) {
            while (j >= 0 && s[i] !== s[j + 1])
                j = next[j];
            if (s[i] === s[j + 1])
                j++;
            next.push(j);
        }

        return next;
    }

    let next = getNext(s);

    if (next[next.length - 1] !== -1 && s.length % (s.length - (next[next.length - 1] + 1)) === 0)
        return true;
    return false;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值