当前位置: 首页 > 知识库问答 >
问题:

用Rabin-Karp算法寻找最长回文子串

乐正瑞
2023-03-14

摘自https://algs4.cs.princeton.edu/53substring/

15.最长回文子串。给定一个字符串s,找出回文(或Watson-crick回文)中最长的子字符串。

解决方案:可以在线性时间内使用后缀树或Manacher算法解决。这里有一个更简单的解决方案,通常在线性时间内运行。首先,我们描述了如何在线性时间内找到所有长度为L的回文子串:使用Karp-Rabin迭代形成每个长度为L的子串(及其反向)的散列,并进行比较。因为你不知道L,重复加倍你对L的猜测,直到你知道最优长度在L和2L之间。然后用二分搜索找到准确的长度。

编辑:这是我根据收到的答案想出的代码。

public static String longestPalindrome(String key) {
    int r = 256;
    long q = longRandomPrime();
    boolean lastFound;
    boolean found;
    int l = 2;

    do {
        lastFound = indexOfPalindromeOfGivenLength(key, l, r, q) >= 0;
        l *= 2;
        found = indexOfPalindromeOfGivenLength(key, l, r, q) >= 0;
    } while (l < key.length() && !(lastFound && !found));

    int left = l / 2;
    int right = l;

    while (left <= right) {
        System.out.printf("Searching for palindromes with length between: %d and %d%n", left, right);

        int i = indexOfPalindromeOfGivenLength(key, left, r, q);
        lastFound = i >= 0;
        int j = indexOfPalindromeOfGivenLength(key, right, r, q);
        found = j >= 0;

        if (lastFound && found) return key.substring(j, j + right);

        int x = left + (right - left) / 2;
        if (!found) right = x;
        else left = x;
    }

    return null;
}

private static int indexOfPalindromeOfGivenLength(String key, int l, int r, long q) {
    System.out.printf("Searching for palindromes with length: %d%n", l);

    for (int i = 0; i + l <= key.length(); i++) {
        String s1 = key.substring(i, i + l);
        long h1 = hash(s1, r, q);
        long h2 = hash(new StringBuilder(s1).reverse().toString(), r, q);

        if (h1 == h2) {
            System.out.printf("Found palindrome: %s of length: %d%n", s1, s1.length());
            return i;
        }
    }
    System.out.printf("No palindromes of length %d exist%n", l);
    return -1;
}

共有1个答案

万勇
2023-03-14

当您到达L,其中有一个长度L的回文子字符串,而没有长度2L的回文子字符串时,您就知道最佳长度在L2L之间。

二找到它你用二分搜索。首先尝试L+ceil(L/2)如果有此长度的回文子字符串,则对L+ceil(L/2)2L执行相同的操作,如果没有此长度的回文子字符串,则在[L,L+ceil(L/2))中搜索。

 类似资料:
  • 我的最新博客地址:我的最新博客 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。 示例 2: 输入: "cbbd" 输出: "bb" 实现如下: /** * @param {string} s * @return {string} */

  • 解决此问题的最佳方法(性能方面)是什么?有人建议我使用后缀树。这是最好的方法吗?

  • 我正试图从leet代码中解决一个问题。我为此写了一个方法。这在local Eclipse中工作得很好,但是当我在leetcode上提交这个解决方案时,它说超过了时间限制。 有人能给我一些建议吗?我可以在下面的代码中修改一些东西,以使它更快地工作?我也可以在这个帖子中输入字符串。 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

  • 下面的代码给出了最长的回文子序列长度。如何修改代码以获得最长的回文子串长度? 下面是一个示例调用:

  • 本文向大家介绍手写算法:查找一个字符串的最长回文子串相关面试题,主要包含被问及手写算法:查找一个字符串的最长回文子串时的应答技巧和注意事项,需要的朋友参考一下 参考回答:

  • 我的第一个想法是修改Manacher算法,它返回最长的回文子字符串(在线性时间内)。 下面是Manacher算法的Java代码: