LeetCode680-验证回文字符串II | 算法练习系列

651 阅读3分钟

这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

前言

js每天一道算法练习题,今天依旧来一道字符串相关的算法题,本题是昨天的验证回文字符串的升级题目,下面我们来看一具体的题目要求

题目描述

给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。

示例 1:

输入: s = "aba"

输出: true

示例 2:

输入: s = "abca"

输出: true

解释: 你可以删除c字符。

示例 3:

输入: s = "abc"

输出: false

解题思路

  • 题目貌似更短了,但和昨天的题目(验证回文字符串)相比其实是更难了,因为它增加了一个操作就是如果删除了字符串中的某一个字符剩下的字符串还是回文的话也符合要求
  • 那我们就可以安装验证正常回文字符串的解题方法来,定义两个指针分别是left和right,初始位置left指向字符串的头部,right指向字符串的尾部。
  • 当left指向的字符和right指向的字符相同时,left++,right--直到left<right不成立
  • 当移动的过程中如果遇到了s[left]和s[right]不相等的情况,这是有两种情况,情况一,删除left当前指向的项,情况二,删除right当前指向的项,这时我们再对删除后left和right之间的字符串进行判断,也就是需要一个辅助函数,当这两种情况中有一种情况符合回文串的要求,则返回true,否则返回false
  • 这里所说的两种情况生成的子串分别是 s[left+1]---s[right]和s[left]---s[right-1],下面上代码
/**
 * @param {string} s
 * @return {boolean}
 */
var validPalindrome = function (s) {
    let left = 0
    let right = s.length-1
    while(left<right){
        if(s[left]!==s[right]){
        //这里就是所说的两种情况,要么前边删除一个字符,要么后边删除一个字符,这两种情况只要有一种符合回文就符合题目要求,说以要用或
            return isPalindrome(s,left+1,right) || isPalindrome(s,left,right-1)
        }
        left++
        right--
    }
    return true
};
//辅助函数的作用就是对删除字符之后对还未遍历的字符串进行遍历判断是否是回文
function isPalindrome(s,left,right){
    while(left<right){
        if(s[left]!==s[right]){
            return false
        }
        left++
        right--
    }
    return true
}

总结

本题是一道处理字符串回文的题目,不过是对正常的回文增加了一个小小的额外条件(可以删除一个字符),所以这题的题目就使用了正常的回文判断的方法再加上贪心就完美解决了问题。如果不使用贪心还可以对字符串进行正常的回文判断如果符合就返回true,不符合的话就通过for循环依次删除一个字符,再对剩下的字符串进行回文判断,这样也可以解决问题,但可能会超时,没有上面的贪心效率高