题解 | #密码截取#

密码截取

http://www.nowcoder.com/practice/3cd4621963e8454594f00199f4536bb1

// 最长回文子串
const input = readline();
const arr = input.split('');
const pArr = []; // pArr[i]表示以arr[i]为中心时的最大回文半径
let pR = -1; // 最大回文半径的右边界
let index = -1; // pR更新时,记录下此时的回文串中心位置

const arr2 = [];
let j = 0;
for (let i = 0, len = 2* arr.length + 1; i < len; i++) {
  if (i % 2 === 0) {
    arr2.push('#');
  } else {
    arr2.push(arr[j++]);
  }
}

for (let i = 0, len = arr2.length; i < len; i++) {
  if (i === 0) {
    pArr.push(1);
    pR = 1;
    index = 0;
    continue;
  }
  if (i >= pR) {
    let k1 = i - 1, k2 = i + 1;
    while (k1 >= 0 && k2 < len) {
      if (arr2[k1] === arr2[k2]) {
        k1--; k2++; continue;
      }
      break;
    }
    pArr.push(k2 - i); // 以i为中心的最大回文半径
    pR = k2;
    index = i;
  } else {
    // 可优化
    const symI = 2*index - i; // 以index为轴,i的对称点i'
    const leftSmall = symI - pArr[symI] + 1; // i'的回文串的左边界下标,记为 左小
    const leftBig = index - pArr[index] + 1; // index的回文串的左边界下标,记为 左大
    if (leftSmall > leftBig) {
      pArr.push(pArr[symI]);                                                                                                              
    } else if (leftSmall < leftBig) {
      pArr.push(symI - leftBig + 1);
    } else {
      let k1 = i - pArr[symI], k2 = i + pArr[symI];
      while (k1 >= 0 && k2 < len) {
        if (arr2[k1] === arr2[k2]) {
          k1--; k2++; continue;
        }
        break;
      }
      pArr.push(k2 - i); // 以i为中心的最大回文半径
      pR = k2;
      index = i;
    }
  }
}

let max = 0;
for (let i = 0, len = pArr.length; i < len; i++) {
  max = Math.max(max, pArr[i]);
}

console.log(max - 1);

全部评论

相关推荐

一名愚蠢的人类:多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞 评论 收藏
分享
拒绝无效加班的小师弟很中意你:求职意向没有,年龄、课程冗余信息可以删掉,需要提升项目经历。排版需要修改。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-26 18:54
说等下个版本吧的发呆爱好者很贪睡:佬最后去了哪家呀
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务