返回

玩转字符串算法,在LeetCode中大显身手

前端

破解字符串算法迷宫:前端开发者的必备指南

字符串算法的基础

作为前端开发者,字符串算法是掌握的基础技能。字符串是一系列字符的集合,是文本数据的一种表示形式。JavaScript 中的字符串可以用单引号或双引号表示。JavaScript 提供了丰富的字符串操作方法,如 charAt(), charCodeAt(), concat(), indexOf() 等,帮助我们对字符串进行各种操作。字符串比较也是字符串算法中的一个基本操作,我们可以使用 ===== 运算符来比较字符串。

字符串算法的常用解题范式

掌握字符串算法常用的解题范式至关重要。暴力破解法是最简单的方法,但效率较低。动态规划法将问题分解成更小的子问题,自底向上地解决问题,适合处理重叠子问题。贪心算法在每一步做出局部最优的选择,适合解决局部最优性质的问题。回溯算法深度优先搜索所有可能的情况,适用于树形结构的问题。

字符串算法实战演练

查找子串

给定一个字符串和一个子串,找到子串在字符串中出现的所有位置。暴力破解法从字符串的第一个字符逐个比较子串,找到子串后记录位置。KMP 算法通过构建失配表减少不必要的比较次数,提高查找效率。

最长公共子串

给定两个字符串,找出这两个字符串的最长公共子串。暴力破解法枚举所有可能的子串,检查这些子串是否存在于两个字符串中,找到最长的公共子串。动态规划法定义一个二维数组,计算出两个字符串的最长公共子串。

最长回文子串

给定一个字符串,找出这个字符串的最长回文子串。暴力破解法枚举所有可能的子串,检查这些子串是否是回文子串,找到最长的回文子串。动态规划法定义一个二维数组,计算出字符串的最长回文子串。

代码示例

// 使用 KMP 算法查找子串
function kmpSearch(string, substring) {
  const n = string.length;
  const m = substring.length;
  const fail = buildFailureTable(substring);
  let i = 0;
  let j = 0;
  const result = [];
  while (i < n) {
    if (string[i] === substring[j]) {
      i++;
      j++;
      if (j === m) {
        result.push(i - j);
        j = fail[j - 1];
      }
    } else if (j > 0) {
      j = fail[j - 1];
    } else {
      i++;
    }
  }
  return result;
}

// 构建失配表
function buildFailureTable(substring) {
  const m = substring.length;
  const fail = new Array(m).fill(0);
  fail[0] = 0;
  let i = 1;
  let j = 0;
  while (i < m) {
    if (substring[i] === substring[j]) {
      fail[i] = j + 1;
      i++;
      j++;
    } else if (j > 0) {
      j = fail[j - 1];
    } else {
      fail[i] = 0;
      i++;
    }
  }
  return fail;
}

// 使用动态规划法计算最长公共子串
function longestCommonSubstring(string1, string2) {
  const n = string1.length;
  const m = string2.length;
  const dp = new Array(n + 1).fill(0).map(() => new Array(m + 1).fill(0));
  let longest = 0;
  let longestEnd = 0;
  for (let i = 1; i <= n; i++) {
    for (let j = 1; j <= m; j++) {
      if (string1[i - 1] === string2[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;
        if (dp[i][j] > longest) {
          longest = dp[i][j];
          longestEnd = i;
        }
      }
    }
  }
  return string1.substring(longestEnd - longest, longestEnd);
}

// 使用动态规划法计算最长回文子串
function longestPalindromicSubstring(string) {
  const n = string.length;
  const dp = new Array(n).fill(0).map(() => new Array(n).fill(false));
  let longest = 1;
  let longestStart = 0;
  for (let i = 0; i < n; i++) {
    dp[i][i] = true;
  }
  for (let length = 2; length <= n; length++) {
    for (let i = 0; i <= n - length; i++) {
      const j = i + length - 1;
      if (length === 2) {
        dp[i][j] = string[i] === string[j];
      } else {
        dp[i][j] = string[i] === string[j] && dp[i + 1][j - 1];
      }
      if (dp[i][j] && length > longest) {
        longest = length;
        longestStart = i;
      }
    }
  }
  return string.substring(longestStart, longestStart + longest);
}

常见问题解答

1. 什么是字符串算法?

字符串算法是用来处理和分析字符串的算法。它们广泛应用于文本搜索、数据压缩、生物信息学和许多其他领域。

2. 字符串算法有哪些类型?

有许多不同类型的字符串算法,包括字符串匹配、字符串搜索、字符串比较、字符串转换和字符串压缩算法。

3. 如何选择合适的字符串算法?

选择合适的字符串算法取决于问题的具体要求,如字符串的长度、模式的复杂性、所需的性能等因素。

4. 字符串算法有哪些应用?

字符串算法在各种领域都有应用,包括文本编辑、网络搜索、自然语言处理、密码学和生物信息学。

5. 学习字符串算法有什么好处?

学习字符串算法可以提高你的问题解决能力、算法设计技能和对计算机科学基础的理解。