关于我把leetcode做的满江红这件事

118 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

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

  示例 1:

输入: s = "aba" 输出: true 示例 2:

输入: s = "abca" 输出: true 解释: 你可以删除c字符。 示例 3:

输入: s = "abc" 输出: false

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/va… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

回文数?那不是简简单单的双指针,可是这题求的是可删除一个数,那么其实我们只要考虑翻转过来的字符串和原来字符串的最大相同子序列的长度是否和原来的字符串的长度差值小于1,如果是那么很显然就是符合条件,求最大相同子序列很快就想到了可以用动态规划的思想,可是空间却超了。

/**
 * @param {string} s
 * @return {boolean}
 */
var validPalindrome = function(s) {
    let reverse=s.split("").reverse();
    let dp=new Array(s.length+1).fill().map(()=>new Array(s.length+1).fill(0));
    for(let i=1;i<=s.length;i++){
        for(let j=1;j<=s.length;j++){
            if(reverse[i-1]===s[j-1]){
                dp[i][j]=dp[i-1][j-1]+1;
            }else{
                dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
            }
        }
    }
    return dp[s.length][s.length]+1>=s.length;
};

我们借助递归的思想:

  • 以"abdda"这个串为例,此时i指向'b',j指向'd',发现不对了。但是有一次删除的机会,我们自己写几个case其实就能发现,此时子串范围为(i+1, j)或(i, j-1)的俩子串只要有任意一个是回文串,则结果就是回文串,否则就不是。

三、AC 代码:

代码一:

/**
 * @param {string} s
 * @return {boolean}
 */
var validPalindrome = function(s) {
    let i=0,j=s.length-1;
    while(i<j){
        if(s[i]!==s[j]){
            return isValid(s,i+1,j)||isValid(s,i,j-1);
        }
        i++;
        j--;
    }
    return true;
    function isValid(s,i,j){
        while(i<j){
            if(s[i]!==s[j]){
                return false;
            }
            i++;j--;
        }
        return true;
    }
};

四、总结:

回文数的判断中双指针是一种很常见的方法。