字符串类题目有两个基本技能:反转字符串和判断一个字符串是否是回文字符串
反转字符串
在 js 中可以直接调用相关 api 实现
主要是将字符串拆分成数组,然后利用数组的反转方法 reverse(),最后拼接成字符串
const str = 'wangyi'const res = str.split('').reverse().join('')console.log(res) // iygnaw
验证回文字符串(LeetCode 125)
回文字符串,就是正着读和倒着读都一样的字符串,比如这样的:'yesey'
一个简单直观的判断方法就是:看这个字符串和它的反转字符串是不是相等
function isPalindrome(str) {// 先反转字符串const reversedStr = str.split('').reverse().join('')// 判断反转前后是否相等return reversedStr === str}
但是回文字符串还有另一个特性:如果从中间位置“劈开”,那么两边的两个子串在内容上是完全对称的。因此我们也可以结合对称性来做判断,并且这是一个非常重要的特性:
function isPalindrome(str){const len = str.lengthfor(let i=0; i<len/2 ; i++ ){// 判断前半部分和后半部分是否对称if(str[i] !== str[len -1-i]){return false}}return true}
回文字符串衍生问题
真题描述:给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串
示例:
输入:’aba’,输出:true
输入:’abca’,输出:true
思路分析:利用回文字符串的对称性和双指针来解
function validPalindrome(str){
// 最多删除一个字符,判断是否是回文字符
const len = str.length
let i = 0,j = len - 1
// 当左右指针均满足对称时,一起向中间前进
while( i < j && str[i]===str[j]){
i++
j--
}
// 工具函数,传左右边界
function isPalindrome(left, right){
while(left < right ){
if(str[left] === str[right]){
left--
right++
}else{
return false
}
}
return true
}
// 尝试判断跳过左指针元素后字符串是否回文
if(isPalindrome(i+1, j)){
return true
}
// 尝试判断跳过右指针元素后字符串是否回文
if(isPalindrome(i, j-1)){
return true
}
return false
}
字符串匹配——正则问题
设计一个支持以下两种操作的数据结构: void addWord(word) bool searchWord(word) search(word) 可以搜索文字或者正则表达式,字符串只包含字母a-z或者., .表示任何一个字母
示例:
addWord(‘bad’)
addWord(‘dad’)
addWord(‘mad’)
search(‘pad’) —> false
search(‘bad’) —> true
search(‘.ad’) —> true
search(‘b..’) —> true
思路分析:
为了降低 search 查找时的复杂度,我们可以考虑以字符串的长度为 key,相同长度的字符串存在一个数组中,这样可以提高我们后续定位的效率。
由于 search() 的参数是字符串或者正则,所以需要判断并分别处理
// includes:判断数组或字符串是否包含
// some: 判断数组中至少有一个元素通过测试函数
function WordDictionary(){
this.words = {}
}
WordDictionary.prototype.addWord = function(word){
const len = word.length
if(this.words[len]){
this.words[len].push(word)
}else{
this.words[len] = [word]
}
}
WordDictionary.prototype.searchWord = function(word){
const len = word.length
if(!this.words[len]){
return false
}
if(!word.includes('.')){
return this.words[len].includes(word)
}
// 包含正则,需要先创建正则对象
const reg = new RegExp(word)
return this.words[len].some(item => reg.test(item))
}
const wordD = new WordDictionary()
wordD.addWord('bad')
wordD.addWord('dad')
console.log(wordD.searchWord('bad')) // true
console.log(wordD.searchWord('.d')) // false
