IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 最长回文子串 -> 正文阅读

[JavaScript知识库]最长回文子串

滑动窗口
遍历时截取出所有子字符串,然后判断子字符串是否是回文,然后和最大长度对比输出

// 方案1 滑动窗口法(“时间复杂度高,一般通过不了”)
var longestPalindrome = function(s) {
// 是否为 回文串。(subStr = ‘’ 稍微体现下编程的严谨性)
const isValid = (subStr = ‘’) => {
const l = subStr.length;
let resFlag = true;

    // 边界:i < l/2
    for(let i = 0; i < l/2; i++) {
        // “对称位置”上的字符不相等,那么肯定就不是 回文串 了
        if (subStr[i] !== subStr[(l - 1) - i]) {
            resFlag = false;
            break;
        }
    }

    return resFlag;
}

const l = s.length;
// curMaxLength 当前回文子串的最大长度,范围:[l, 1]
for (let curMaxLength = l; curMaxLength > 0; curMaxLength--) {
    // 在 curMaxLength 下,curStartIndex的有效范围为 [0, ((l + 1) - curMaxLength) )
    for (let curStartIndex = 0; curStartIndex < ((l + 1) - curMaxLength); curStartIndex++) {
        const subStr = s.substr(curStartIndex, curMaxLength);
        // 一旦符合 回文串 ,那么当前子串一定是我们的预期答案(“之一”)
        // 因为我们 curMaxLength 在一次次遍历中在递减
        if (isValid(subStr)) {
            return subStr;
        }
    }
}



// 边界:可能 l为0 、然后直接到这里了,需要返回空字符串(不过题目 1 <= s.length <= 1000 ,故 可省略 )
return "";

}

动态判划

从最小的子串开始,通过二维数组和首尾索引记录当前子字符串的位置,如果回文置为true,故之后的较长子串只需判断首尾是否相等和首+ 1尾 - 1的子串是否为true即可,最小回文子串a、 aa、 aba构成较长子串,对应的设置逻辑为二维数组相同索引为true、s[i] === s[j] && ((j + 1) - i) < 3时为true

// 方案2 动态规划,(s[i] === s[j] && dp[i + 1][j - 1]) || (s[i] === s[j] && ((j + 1) - i) < 3[i] )
var longestPalindrome = function(s) {
const l = s.length,
// 1)含义:s[i][j] 表示s[i, j]是否为回文串(双闭区间)
// 初始化1:dp, n*n 个值都初始化为 false
dp = new Array(l).fill(false).map(item => new Array(l).fill(false));
// 当前 最长回文子串 的开始下标、最大长度
let maxStartIndex = 0,
// 边界:maxLength 初始化为1。不然会有问题、可自行思考~
maxLength = 1;

// 初始化2:dp对角线上值 均为 true 
for (let i = 0; i < l; i++) {
    for(let j = 0; j < l; j++) {
        if (i === j) {
            dp[i][j] = true;
        }
    }
}

// 2)状态转移方程:
// s[i][j] = (s[i] === s[j] && dp[i + 1][j - 1]) || (s[i] === s[j] && ((j + 1) - i) < 3)
// s[i][j] = (当前首、尾字符相同 && 首、尾各往中间缩1位依旧是回文串) 
// 或 (当前首、尾字符相同 && 当前首、尾位置间隔 < 3) 如 "bb" 这种长度小于3时,只要保证 首、尾字符相同即可
for (let j = 1; j < l; j++) {
    for(let i = 0; i < j; i++) {
        if ((s[i] === s[j] && dp[i + 1][j - 1]) || (s[i] === s[j] && ((j + 1) - i) < 3)) {
            dp[i][j] = true;
            // 当前s[i, j]为回文串了,才看是否需要更新 maxStartIndex、maxLength 值
            // 3)当 s[i, j]为回文串 && (j + 1) - i) > maxLength 时,更新 maxStartIndex、maxLength 值
            if (((j + 1) - i) > maxLength) {
                maxStartIndex = i;
                maxLength = ((j + 1) - i);
            }
        } else {
            dp[i][j] = false;
        }
    }
}

// 最后根据 “我们所维护的” maxStartIndex, maxLength 得出相应的子串
return s.substr(maxStartIndex, maxLength);

}

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-07 13:45:45  更:2021-10-07 13:46:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 0:45:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码