当前位置: 首页 > news >正文

29-验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。

方法一:筛选反转法

该方法的核心思路是先筛选出字符串中的字母和数字字符,并将大写字母转换为小写字母,然后将筛选后的字符串反转,最后比较原筛选字符串和反转后的字符串是否相同。

function isPalindrome(s: string): boolean {
    // 筛选出字母和数字字符,并转换为小写
    let filtered = '';
    for (let char of s) {
        if (/[a-zA-Z0-9]/.test(char)) {
            filtered += char.toLowerCase();
        }
    }
    // 反转筛选后的字符串
    let reversed = filtered.split('').reverse().join('');
    return filtered === reversed;
}
复杂度分析
  • 时间复杂度:(O(n)),其中 n 是字符串 s 的长度。首先需要遍历一次字符串 s 进行筛选,时间复杂度为 (O(n));然后对筛选后的字符串进行反转,其长度最多为 n,时间复杂度也为 (O(n))。因此,总的时间复杂度为 (O(n))。
  • 空间复杂度:(O(n)),主要用于存储筛选后的字符串和反转后的字符串,其长度最多为 n。

方法二:双指针法

双指针法使用两个指针分别从字符串的首尾开始向中间移动,在移动过程中跳过非字母数字字符,并比较对应位置的字符是否相同。

function isPalindrome(s: string): boolean {
    let left = 0;
    let right = s.length - 1;
    while (left < right) {
        // 跳过非字母数字字符
        while (left < right &&!isAlphanumeric(s[left])) {
            left++;
        }
        while (left < right &&!isAlphanumeric(s[right])) {
            right--;
        }
        // 比较字符,忽略大小写
        if (left < right && s[left].toLowerCase()!== s[right].toLowerCase()) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

function isAlphanumeric(char: string): boolean {
    return /[a-zA-Z0-9]/.test(char);
}
复杂度分析
  • 时间复杂度:(O(n)),其中 n 是字符串 s 的长度。两个指针最多遍历字符串一次,因此时间复杂度为 (O(n))。
  • 空间复杂度:(O(1)),只使用了常数级的额外空间,主要用于存储指针。

方法三:递归法

递归法通过不断缩小字符串的范围,递归地判断子字符串是否为回文串。

function isPalindrome(s: string): boolean {
    return helper(s, 0, s.length - 1);
}

function helper(s: string, left: number, right: number): boolean {
    // 跳过非字母数字字符
    while (left < right &&!isAlphanumeric(s[left])) {
        left++;
    }
    while (left < right &&!isAlphanumeric(s[right])) {
        right--;
    }
    if (left >= right) {
        return true;
    }
    // 比较字符,忽略大小写
    if (s[left].toLowerCase()!== s[right].toLowerCase()) {
        return false;
    }
    return helper(s, left + 1, right - 1);
}

function isAlphanumeric(char: string): boolean {
    return /[a-zA-Z0-9]/.test(char);
}
复杂度分析
  • 时间复杂度:(O(n)),其中 n 是字符串 s 的长度。递归过程中,每次递归调用都会将问题规模缩小,最多需要 (n/2) 次递归调用,因此时间复杂度为 (O(n))。
  • 空间复杂度:(O(n)),主要是递归调用栈的空间开销,最坏情况下递归深度为 (n/2),因此空间复杂度为 (O(n))。

测试用例

const testString = "A man, a plan, a canal: Panama";
console.log(isPalindrome(testString)); 

相关文章:

  • 【C++初阶】类与对象(下)
  • Docker 运行 GPUStack 的详细教程
  • 蓝桥杯刷题周计划(第二周)
  • Scala 中trait的线性化规则(Linearization Rule)和 super 的调用行为
  • GC安全点导致停顿时间过长的案例
  • 深入解析跨域问题及其解决方案:从原理到代码实践
  • (安全防御)旁挂组网双机热备负载分担实验
  • coding ability 展开第二幕(双指针——巩固篇)超详细!!!!
  • Codeforces Round 976 (Div. 2) (部分题解)
  • webtinyserver讲解
  • TypeScript系列06-模块系统与命名空间
  • 《Linux栈破坏了,如何还原》
  • Element Plus中的树组件的具体用法(持续更新!)
  • 分布式Consul面试题及参考答案
  • 《C陷阱与缺陷》读书笔记(一)
  • stm32中分析UART中IDLE,RXNE,TC,TXE这些标志位的作用
  • 【商城实战(15)】订单创建与提交:技术与实战的深度融合
  • Java:LocalDatTime(代替Calendar)、ZoneDateTime(时区时间)
  • Python 中 `sort()` 和 `sorted()` 的用法与区别
  • 课程《Deep Learning Specialization》
  • 西安做网站微信公司/免费网站模板网
  • wordpress 自动换行/一键优化软件
  • 动态网站设计/百度seo培训班
  • 凡科网站做的好不好/百度seo怎么样优化
  • 泉州seo优化/seo网络优化是什么工作
  • 如何设置网站关键字/网络营销课程学什么