「字符串题」1. 最长回文字串

338 阅读2分钟

打造保姆级题解,一次只写一种解法降低学习成本。

Leetcode 5.最长回文子串

image.png

解题思路

找到最长的回文字串,可以采用枚举的方式找到全部的回文字串,再从中得到最长的那个。

image.png

babad,这个字符串中,如果 dp[2][2] 是回文字串,那么。dp[1][3] 也是回文字串,也就是说,子问题的结果可以推导出更大问题的结果。这里存在最优子结构,所以我们采用动态规划的方式来求解。

  1. 定义状态

dp[i][j] 表示当前的结果是否是最优子结构,因为要一个开头,一个结尾,所有需要一个二维数组。

  1. 得出状态转移返程

当前项是否是

对数组进行遍历,满足以下两种情况时dp[i][j]的结果是 true,否则是false 开始位置和结束位置指向的数相等,且当前的两个数相邻或是同一个数。 开始位置和结束位置指向的数相等,且满足子结构的结果是true

dp[i][j] = s[i] == s[j] && (j - i < 2 || dp[i+1][j-1]);

  1. 初始化状态,都是 false

  2. 返回结果

代码

var longestPalindrome = function(s) {
    let n = s.length;
    let res = '';
    let dp = Array.from(new Array(n),() => new Array(n).fill(false));//初始化数组 
    for(let i = n-1;i >= 0;i--){// 从后往前遍历
        for(let j = i;j < n;j++){ // 从前往后遍历
            dp[i][j] = s[i] == s[j] && (j - i < 2 || dp[i+1][j-1]); 
            if(dp[i][j] && j - i +1 > res.length){ 
                res = s.substring(i,j+1); // 当前回文子串比之前的大,更新最大长度
            }
        }
    }
    return res;
};

详细解释

1. 最优子结构

最优子结构是说可以从子问题的最优结果,推出更大规模问题的最优结果。

比如要从全校选出同学去参加全区的跑步比赛,全校有10个班级的同学,计算每个班跑最快的同学是子问题,在知道所有子问题的答案后就可以在这10个b班级的最高分中得到全校最高分。

2. 重叠子问题

image.png

在做斐波那契算法的时候,fib(3)的两次结果是重复的,这就是重叠子问题。

2. 回文字符串

“回文串”是一个正读和反读都一样的字符串,初始化标志flag=true,比如“level”或者“noon”等等就是回文串。

3. subString

str.substring(start, end)方法同样是截取字符串,两个参数分别表示开始和结束的位数,类似slice,但是不同的是substring不接受负数,并且如果start值大于end的值,则会自动交换两个位置

let str = "123456"
str.substring.subString(0, 1) // 1
str.substring.subString(5) // 6

4. Array.from

Array.from()方法从类似数组或可迭代对象创建一个新的(浅拷贝)的数组实例..

Array.from(arrayLike,mapFn,thisArg)

  • arrayLike:必选,想要转换成数组的伪数组对象或可迭代对象
  • mapFn:可选,如果指定了该参数,新数组中的每个元素会执行该函数
  • thisArg:可选,执行回调函数mapFn时this对象