返回

算法思维与回文魅力:探索最长回文子串

前端

在代码世界的广阔舞台上,字符串操作是程序员手中不可或缺的利器。无论是处理文本数据、构建复杂的应用系统,还是解决各种算法难题,字符串的操作能力都扮演着至关重要的角色。在这场探索字符串奥秘的旅程中,最长回文子串这个经典算法问题脱颖而出,让我们一起踏上破解它的征途,领略算法思维与回文魅力的交织碰撞。

最长回文子串的定义:

回文子串指的是从字符串中选取的连续字符序列,无论从左到右还是从右到左读取,它都呈现出相同的效果。比如,在字符串 "abba" 中,"abba" 和 "bb" 都是回文子串。

算法思维的闪耀:

解决最长回文子串问题,关键在于运用算法思维,寻找巧妙的解决方案。其中,最常用的一种方法是"中心扩展法"。我们从字符串的每个字符出发,以它为中心向两边同时扩展,比较扩展过程中遇到字符是否相同,从而判断是否存在回文子串,并记录最长的一个。

Javascript:从诗意中书写代码

在Javascript的诗意旋律中,最长回文子串的算法代码可以这样谱写:

/**
 * 获取最长回文子串
 * @param {string} str 字符串
 * @returns {string} 最长回文子串
 */
const longestPalindrome = (str) => {
  // 空字符串或长度为1,直接返回
  if (str.length <= 1) {
    return str;
  }

  // 初始化最长回文子串的长度和起始索引
  let maxLen = 1;
  let startIndex = 0;

  // 从字符串的每个字符出发,以它为中心向两边同时扩展
  for (let i = 0; i < str.length; i++) {
    let [left, right] = [i - 1, i + 1];
    while (left >= 0 && right < str.length && str[left] === str[right]) {
      if (right - left + 1 > maxLen) {
        maxLen = right - left + 1;
        startIndex = left;
      }
      left--;
      right++;
    }

    // 考虑中心为两个字符的情况
    [left, right] = [i, i + 1];
    while (left >= 0 && right < str.length && str[left] === str[right]) {
      if (right - left + 1 > maxLen) {
        maxLen = right - left + 1;
        startIndex = left;
      }
      left--;
      right++;
    }
  }

  // 返回最长回文子串
  return str.substring(startIndex, startIndex + maxLen);
};

// 测试用例
console.log(longestPalindrome('abba')); // "abba"
console.log(longestPalindrome('babad')); // "bab"
console.log(longestPalindrome('cbbd')); // "bb"
console.log(longestPalindrome('aacabdkacaa')); // "aca"

Typescript:严谨而优雅

在Typescript的严谨优雅中,最长回文子串的代码可以这样舞动:

/**
 * 获取最长回文子串
 * @param {string} str 字符串
 * @returns {string} 最长回文子串
 */
const longestPalindrome = (str: string): string => {
  // 空字符串或长度为1,直接返回
  if (str.length <= 1) {
    return str;
  }

  // 初始化最长回文子串的长度和起始索引
  let maxLen = 1;
  let startIndex = 0;

  // 从字符串的每个字符出发,以它为中心向两边同时扩展
  for (let i = 0; i < str.length; i++) {
    let [left, right] = [i - 1, i + 1];
    while (left >= 0 && right < str.length && str[left] === str[right]) {
      if (right - left + 1 > maxLen) {
        maxLen = right - left + 1;
        startIndex = left;
      }
      left--;
      right++;
    }

    // 考虑中心为两个字符的情况
    [left, right] = [i, i + 1];
    while (left >= 0 && right < str.length && str[left] === str[right]) {
      if (right - left + 1 > maxLen) {
        maxLen = right - left + 1;
        startIndex = left;
      }
      left--;
      right++;
    }
  }

  // 返回最长回文子串
  return str.substring(startIndex, startIndex + maxLen);
};

// 测试用例
console.log(longestPalindrome('abba')); // "abba"
console.log(longestPalindrome('babad')); // "bab"
console.log(longestPalindrome('cbbd')); // "bb"
console.log(longestPalindrome('aacabdkacaa')); // "aca"

Python:简洁而清晰

在Python的简洁清晰中,最长回文子串的代码可以这样流淌:

def longest_palindrome(str):
  """
  获取最长回文子串
  :param str: 字符串
  :return: 最长回文子串
  """

  # 空字符串或长度为1,直接返回
  if len(str) <= 1:
    return str

  # 初始化最长回文子串的长度和起始索引
  max_len = 1
  start_index = 0

  # 从字符串的每个字符出发,以它为中心向两边同时扩展
  for i in range(len(str)):
    left, right = i - 1, i + 1
    while left >= 0 and right < len(str) and str[left] == str[right]:
      if right - left + 1 > max_len:
        max_len = right - left + 1
        start_index = left
      left -= 1
      right += 1

    # 考虑中心为两个字符的情况
    left, right = i, i + 1
    while left >= 0 and right < len(str) and str[left] == str[right]:
      if right - left + 1 > max_len:
        max_len = right - left + 1
        start_index = left
      left -= 1
      right += 1

  # 返回最长回文子串
  return str[start_index:start_index + max_len]


# 测试用例
print(longest_palindrome('abba'))  # "abba"
print(longest_palindrome('babad'))  # "bab"
print(longest_palindrome('cbbd'))  # "bb"
print(longest_palindrome('aacabdkacaa'))  # "aca"