📜  最长回文子串|套装1

📅  最后修改于: 2021-05-04 22:15:34             🧑  作者: Mango

给定一个字符串,找到最长的子字符串,即回文。

例如,

Input: Given string :"forgeeksskeegfor", 
Output: "geeksskeeg"

Input: Given string :"Geeks", 
Output: "ee"

方法1蛮力。
方法:简单的方法是检查每个子字符串是否该子字符串是回文。首先,运行三个嵌套循环,外部两个循环通过固定转角字符来逐个拾取所有子字符串,内部循环检查所拾取的子字符串是否为回文。

C++
// A C++ solution for longest palindrome
#include 
using namespace std;
 
// Function to print a substring str[low..high]
void printSubStr(string str, int low, int high)
{
    for (int i = low; i <= high; ++i)
        cout << str[i];
}
 
// This function prints the
// longest palindrome substring
// It also returns the length
// of the longest palindrome
int longestPalSubstr(string str)
{
    // get length of input string
    int n = str.size();
 
    // All substrings of length 1
    // are palindromes
    int maxLength = 1, start = 0;
 
    // Nested loop to mark start and end index
    for (int i = 0; i < str.length(); i++) {
        for (int j = i; j < str.length(); j++) {
            int flag = 1;
 
            // Check palindrome
            for (int k = 0; k < (j - i + 1) / 2; k++)
                if (str[i + k] != str[j - k])
                    flag = 0;
 
            // Palindrome
            if (flag && (j - i + 1) > maxLength) {
                start = i;
                maxLength = j - i + 1;
            }
        }
    }
 
    cout << "Longest palindrome substring is: ";
    printSubStr(str, start, start + maxLength - 1);
 
    // return length of LPS
    return maxLength;
}
 
// Driver Code
int main()
{
    string str = "forgeeksskeegfor";
    cout << "\nLength is: "
         << longestPalSubstr(str);
    return 0;
}


Java
// A Java solution for longest palindrome
import java.util.*;
 
class GFG{
 
// Function to print a subString str[low..high]
static void printSubStr(String str, int low, int high)
{
    for (int i = low; i <= high; ++i)
        System.out.print(str.charAt(i));
}
 
// This function prints the
// longest palindrome subString
// It also returns the length
// of the longest palindrome
static int longestPalSubstr(String str)
{
    // get length of input String
    int n = str.length();
 
    // All subStrings of length 1
    // are palindromes
    int maxLength = 1, start = 0;
 
    // Nested loop to mark start and end index
    for (int i = 0; i < str.length(); i++) {
        for (int j = i; j < str.length(); j++) {
            int flag = 1;
 
            // Check palindrome
            for (int k = 0; k < (j - i + 1) / 2; k++)
                if (str.charAt(i + k) != str.charAt(j - k))
                    flag = 0;
 
            // Palindrome
            if (flag!=0 && (j - i + 1) > maxLength) {
                start = i;
                maxLength = j - i + 1;
            }
        }
    }
 
    System.out.print("Longest palindrome subString is: ");
    printSubStr(str, start, start + maxLength - 1);
 
    // return length of LPS
    return maxLength;
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "forgeeksskeegfor";
    System.out.print("\nLength is: "
         + longestPalSubstr(str));
}
}
 
// This code is contributed by shikhasingrajput


Python3
# A Python3 solution for longest palindrome
 
# Function to pra subString str[low..high]
def printSubStr(str, low, high):
     
    for i in range(low, high + 1):
        print(str[i], end = "")
 
# This function prints the
# longest palindrome subString
# It also returns the length
# of the longest palindrome
def longestPalSubstr(str):
     
    # Get length of input String
    n = len(str)
     
    # All subStrings of length 1
    # are palindromes
    maxLength = 1
    start = 0
     
    # Nested loop to mark start
    # and end index
    for i in range(n):
        for j in range(i, n):
            flag = 1
             
            # Check palindrome
            for k in range(0, ((j - i) // 2) + 1):
                if (str[i + k] != str[j - k]):
                    flag = 0
 
            # Palindrome
            if (flag != 0 and (j - i + 1) > maxLength):
                start = i
                maxLength = j - i + 1
                 
    print("Longest palindrome subString is: ", end = "")
    printSubStr(str, start, start + maxLength - 1)
 
    # Return length of LPS
    return maxLength
 
# Driver Code
if __name__ == '__main__':
 
    str = "forgeeksskeegfor"
     
    print("\nLength is: ", longestPalSubstr(str))
 
# This code is contributed by 29AjayKumar


C#
// A C# solution for longest palindrome
using System;
 
class GFG{
 
// Function to print a subString str[low..high]
static void printSubStr(String str, int low, int high)
{
    for (int i = low; i <= high; ++i)
        Console.Write(str[i]);
}
 
// This function prints the
// longest palindrome subString
// It also returns the length
// of the longest palindrome
static int longestPalSubstr(String str)
{
    // get length of input String
    int n = str.Length;
 
    // All subStrings of length 1
    // are palindromes
    int maxLength = 1, start = 0;
 
    // Nested loop to mark start and end index
    for (int i = 0; i < str.Length; i++) {
        for (int j = i; j < str.Length; j++) {
            int flag = 1;
 
            // Check palindrome
            for (int k = 0; k < (j - i + 1) / 2; k++)
                if (str[i + k] != str[j - k])
                    flag = 0;
 
            // Palindrome
            if (flag!=0 && (j - i + 1) > maxLength) {
                start = i;
                maxLength = j - i + 1;
            }
        }
    }
 
    Console.Write("longest palindrome subString is: ");
    printSubStr(str, start, start + maxLength - 1);
 
    // return length of LPS
    return maxLength;
}
 
// Driver Code
public static void Main(String[] args)
{
    String str = "forgeeksskeegfor";
    Console.Write("\nLength is: "
         + longestPalSubstr(str));
}
}
 
// This code is contributed by shikhasingrajput


C++
// A C++ dynamic programming
// solution for longest palindrome
 
#include 
using namespace std;
 
// Function to print a substring
// str[low..high]
void printSubStr(
    string str, int low, int high)
{
    for (int i = low; i <= high; ++i)
        cout << str[i];
}
 
// This function prints the
// longest palindrome substring
// It also returns the length of
// the longest palindrome
int longestPalSubstr(string str)
{
    // get length of input string
    int n = str.size();
 
    // table[i][j] will be false if substring
    // str[i..j] is not palindrome.
    // Else table[i][j] will be true
    bool table[n][n];
 
    memset(table, 0, sizeof(table));
 
    // All substrings of length 1
    // are palindromes
    int maxLength = 1;
 
    for (int i = 0; i < n; ++i)
        table[i][i] = true;
 
    // check for sub-string of length 2.
    int start = 0;
    for (int i = 0; i < n - 1; ++i) {
        if (str[i] == str[i + 1]) {
            table[i][i + 1] = true;
            start = i;
            maxLength = 2;
        }
    }
 
    // Check for lengths greater than 2.
    // k is length of substring
    for (int k = 3; k <= n; ++k) {
        // Fix the starting index
        for (int i = 0; i < n - k + 1; ++i) {
            // Get the ending index of substring from
            // starting index i and length k
            int j = i + k - 1;
 
            // checking for sub-string from ith index to
            // jth index iff str[i+1] to str[j-1] is a
            // palindrome
            if (table[i + 1][j - 1] && str[i] == str[j]) {
                table[i][j] = true;
 
                if (k > maxLength) {
                    start = i;
                    maxLength = k;
                }
            }
        }
    }
 
    cout << "Longest palindrome substring is: ";
    printSubStr(str, start, start + maxLength - 1);
 
    // return length of LPS
    return maxLength;
}
 
// Driver Code
int main()
{
    string str = "forgeeksskeegfor";
    cout << "\nLength is: "
         << longestPalSubstr(str);
    return 0;
}


Java
// Java Solution
public class LongestPalinSubstring {
    // A utility function to print
    // a substring str[low..high]
    static void printSubStr(
        String str, int low, int high)
    {
        System.out.println(
            str.substring(
                low, high + 1));
    }
 
    // This function prints the longest
    // palindrome substring of str[].
    // It also returns the length of the
    // longest palindrome
    static int longestPalSubstr(String str)
    {
        // get length of input string
        int n = str.length();
 
        // table[i][j] will be false if
        // substring str[i..j] is not palindrome.
        // Else table[i][j] will be true
        boolean table[][] = new boolean[n][n];
 
        // All substrings of length 1 are palindromes
        int maxLength = 1;
        for (int i = 0; i < n; ++i)
            table[i][i] = true;
 
        // check for sub-string of length 2.
        int start = 0;
        for (int i = 0; i < n - 1; ++i) {
            if (str.charAt(i) == str.charAt(i + 1)) {
                table[i][i + 1] = true;
                start = i;
                maxLength = 2;
            }
        }
 
        // Check for lengths greater than 2.
        // k is length of substring
        for (int k = 3; k <= n; ++k) {
 
            // Fix the starting index
            for (int i = 0; i < n - k + 1; ++i) {
                // Get the ending index of substring from
                // starting index i and length k
                int j = i + k - 1;
 
                // checking for sub-string from ith index to
                // jth index iff str.charAt(i+1) to
                // str.charAt(j-1) is a palindrome
                if (table[i + 1][j - 1]
                    && str.charAt(i) == str.charAt(j)) {
                    table[i][j] = true;
 
                    if (k > maxLength) {
                        start = i;
                        maxLength = k;
                    }
                }
            }
        }
        System.out.print("Longest palindrome substring is; ");
        printSubStr(str, start,
                    start + maxLength - 1);
 
        // return length of LPS
        return maxLength;
    }
 
    // Driver program to test above functions
    public static void main(String[] args)
    {
 
        String str = "forgeeksskeegfor";
        System.out.println("Length is: " + longestPalSubstr(str));
    }
}
 
// This code is contributed by Sumit Ghosh


Python
# Python program
 
import sys
 
# A utility function to print a
# substring str[low..high]
def printSubStr(st, low, high) :
    sys.stdout.write(st[low : high + 1])
    sys.stdout.flush()
    return ''
 
# This function prints the longest palindrome
# substring of st[]. It also returns the length
# of the longest palindrome
def longestPalSubstr(st) :
    n = len(st) # get length of input string
 
    # table[i][j] will be false if substring
    # str[i..j] is not palindrome. Else
    # table[i][j] will be true
    table = [[0 for x in range(n)] for y
                          in range(n)]
     
    # All substrings of length 1 are
    # palindromes
    maxLength = 1
    i = 0
    while (i < n) :
        table[i][i] = True
        i = i + 1
     
    # check for sub-string of length 2.
    start = 0
    i = 0
    while i < n - 1 :
        if (st[i] == st[i + 1]) :
            table[i][i + 1] = True
            start = i
            maxLength = 2
        i = i + 1
     
    # Check for lengths greater than 2.
    # k is length of substring
    k = 3
    while k <= n :
        # Fix the starting index
        i = 0
        while i < (n - k + 1) :
             
            # Get the ending index of
            # substring from starting
            # index i and length k
            j = i + k - 1
     
            # checking for sub-string from
            # ith index to jth index iff
            # st[i + 1] to st[(j-1)] is a
            # palindrome
            if (table[i + 1][j - 1] and
                      st[i] == st[j]) :
                table[i][j] = True
     
                if (k > maxLength) :
                    start = i
                    maxLength = k
            i = i + 1
        k = k + 1
    print "Longest palindrome substring is: ", printSubStr(st, start,
                                               start + maxLength - 1)
 
    return maxLength # return length of LPS
 
 
# Driver program to test above functions
st = "forgeeksskeegfor"
l = longestPalSubstr(st)
print "Length is:", l
 
# This code is contributed by Nikita Tiwari.


C#
// C# Solution
using System;
 
class GFG {
 
    // A utility function to print a
    // substring str[low...( high - (low+1))]
    static void printSubStr(string str, int low,
                            int high)
    {
        Console.WriteLine(str.Substring(low,
                                        high - low + 1));
    }
 
    // This function prints the longest
    // palindrome substring of str[].
    // It also returns the length of the
    // longest palindrome
    static int longestPalSubstr(string str)
    {
 
        // Get length of input string
        int n = str.Length;
 
        // Table[i, j] will be false if substring
        // str[i..j] is not palindrome. Else
        // table[i, j] will be true
        bool[, ] table = new bool[n, n];
 
        // All substrings of length 1 are palindromes
        int maxLength = 1;
        for (int i = 0; i < n; ++i)
            table[i, i] = true;
 
        // Check for sub-string of length 2.
        int start = 0;
 
        for (int i = 0; i < n - 1; ++i) {
            if (str[i] == str[i + 1]) {
                table[i, i + 1] = true;
                start = i;
                maxLength = 2;
            }
        }
 
        // Check for lengths greater than 2.
        // k is length of substring
        for (int k = 3; k <= n; ++k) {
 
            // Fix the starting index
            for (int i = 0; i < n - k + 1; ++i) {
 
                // Get the ending index of substring from
                // starting index i and length k
                int j = i + k - 1;
 
                // Checking for sub-string from ith index
                // to jth index iff str.charAt(i+1) to
                // str.charAt(j-1) is a palindrome
                if (table[i + 1, j - 1] && str[i] == str[j]) {
                    table[i, j] = true;
                    if (k > maxLength) {
                        start = i;
                        maxLength = k;
                    }
                }
            }
        }
        Console.Write("Longest palindrome substring is: ");
        printSubStr(str, start, start + maxLength - 1);
 
        // Return length of LPS
        return maxLength;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        string str = "forgeeksskeegfor";
 
        Console.WriteLine("Length is: " + longestPalSubstr(str));
    }
}
 
// This code is contributed by SoumikMondal


输出:

Longest palindrome subString is: geeksskeeg
Length is:  10

复杂度分析:

  • 时间复杂度: O(n ^ 3)。
    这种方法需要三个嵌套循环才能找到最长的回文子串,因此时间复杂度为O(n ^ 3)。
  • 辅助复杂度:O(1)。
    由于不需要额外的空间。

方法2动态编程。
方法:可以通过存储子问题的结果来减少时间复杂度。这个想法类似于这篇文章。

  1. 保持以自下而上的方式填充的布尔表[n] [n]。
  2. 如果子字符串是回文,则table [i] [j]的值为true,否则为false。
  3. 要计算table [i] [j],请检查table [i + 1] [j-1]的值,如果该值为true且str [i]与str [j]相同,则我们将table [i] ] [j]是。
  4. 否则,将table [i] [j]的值设置为false。
  5. 我们必须先前为长度= 1且长度= 2的子串填写表格,因为
    正如我们所发现的,如果table [i + 1] [j-1]是true或false,那么在
    (i)length == 1,可以说i = 2,j = 2,并且i + 1,j-1不位于[i,j]之间
    (ii)length == 2,再说i = 2,j = 3,而i + 1,j-1也不位于[i,j]之间。

下面是上述方法的实现:

C++

// A C++ dynamic programming
// solution for longest palindrome
 
#include 
using namespace std;
 
// Function to print a substring
// str[low..high]
void printSubStr(
    string str, int low, int high)
{
    for (int i = low; i <= high; ++i)
        cout << str[i];
}
 
// This function prints the
// longest palindrome substring
// It also returns the length of
// the longest palindrome
int longestPalSubstr(string str)
{
    // get length of input string
    int n = str.size();
 
    // table[i][j] will be false if substring
    // str[i..j] is not palindrome.
    // Else table[i][j] will be true
    bool table[n][n];
 
    memset(table, 0, sizeof(table));
 
    // All substrings of length 1
    // are palindromes
    int maxLength = 1;
 
    for (int i = 0; i < n; ++i)
        table[i][i] = true;
 
    // check for sub-string of length 2.
    int start = 0;
    for (int i = 0; i < n - 1; ++i) {
        if (str[i] == str[i + 1]) {
            table[i][i + 1] = true;
            start = i;
            maxLength = 2;
        }
    }
 
    // Check for lengths greater than 2.
    // k is length of substring
    for (int k = 3; k <= n; ++k) {
        // Fix the starting index
        for (int i = 0; i < n - k + 1; ++i) {
            // Get the ending index of substring from
            // starting index i and length k
            int j = i + k - 1;
 
            // checking for sub-string from ith index to
            // jth index iff str[i+1] to str[j-1] is a
            // palindrome
            if (table[i + 1][j - 1] && str[i] == str[j]) {
                table[i][j] = true;
 
                if (k > maxLength) {
                    start = i;
                    maxLength = k;
                }
            }
        }
    }
 
    cout << "Longest palindrome substring is: ";
    printSubStr(str, start, start + maxLength - 1);
 
    // return length of LPS
    return maxLength;
}
 
// Driver Code
int main()
{
    string str = "forgeeksskeegfor";
    cout << "\nLength is: "
         << longestPalSubstr(str);
    return 0;
}

Java

// Java Solution
public class LongestPalinSubstring {
    // A utility function to print
    // a substring str[low..high]
    static void printSubStr(
        String str, int low, int high)
    {
        System.out.println(
            str.substring(
                low, high + 1));
    }
 
    // This function prints the longest
    // palindrome substring of str[].
    // It also returns the length of the
    // longest palindrome
    static int longestPalSubstr(String str)
    {
        // get length of input string
        int n = str.length();
 
        // table[i][j] will be false if
        // substring str[i..j] is not palindrome.
        // Else table[i][j] will be true
        boolean table[][] = new boolean[n][n];
 
        // All substrings of length 1 are palindromes
        int maxLength = 1;
        for (int i = 0; i < n; ++i)
            table[i][i] = true;
 
        // check for sub-string of length 2.
        int start = 0;
        for (int i = 0; i < n - 1; ++i) {
            if (str.charAt(i) == str.charAt(i + 1)) {
                table[i][i + 1] = true;
                start = i;
                maxLength = 2;
            }
        }
 
        // Check for lengths greater than 2.
        // k is length of substring
        for (int k = 3; k <= n; ++k) {
 
            // Fix the starting index
            for (int i = 0; i < n - k + 1; ++i) {
                // Get the ending index of substring from
                // starting index i and length k
                int j = i + k - 1;
 
                // checking for sub-string from ith index to
                // jth index iff str.charAt(i+1) to
                // str.charAt(j-1) is a palindrome
                if (table[i + 1][j - 1]
                    && str.charAt(i) == str.charAt(j)) {
                    table[i][j] = true;
 
                    if (k > maxLength) {
                        start = i;
                        maxLength = k;
                    }
                }
            }
        }
        System.out.print("Longest palindrome substring is; ");
        printSubStr(str, start,
                    start + maxLength - 1);
 
        // return length of LPS
        return maxLength;
    }
 
    // Driver program to test above functions
    public static void main(String[] args)
    {
 
        String str = "forgeeksskeegfor";
        System.out.println("Length is: " + longestPalSubstr(str));
    }
}
 
// This code is contributed by Sumit Ghosh

Python

# Python program
 
import sys
 
# A utility function to print a
# substring str[low..high]
def printSubStr(st, low, high) :
    sys.stdout.write(st[low : high + 1])
    sys.stdout.flush()
    return ''
 
# This function prints the longest palindrome
# substring of st[]. It also returns the length
# of the longest palindrome
def longestPalSubstr(st) :
    n = len(st) # get length of input string
 
    # table[i][j] will be false if substring
    # str[i..j] is not palindrome. Else
    # table[i][j] will be true
    table = [[0 for x in range(n)] for y
                          in range(n)]
     
    # All substrings of length 1 are
    # palindromes
    maxLength = 1
    i = 0
    while (i < n) :
        table[i][i] = True
        i = i + 1
     
    # check for sub-string of length 2.
    start = 0
    i = 0
    while i < n - 1 :
        if (st[i] == st[i + 1]) :
            table[i][i + 1] = True
            start = i
            maxLength = 2
        i = i + 1
     
    # Check for lengths greater than 2.
    # k is length of substring
    k = 3
    while k <= n :
        # Fix the starting index
        i = 0
        while i < (n - k + 1) :
             
            # Get the ending index of
            # substring from starting
            # index i and length k
            j = i + k - 1
     
            # checking for sub-string from
            # ith index to jth index iff
            # st[i + 1] to st[(j-1)] is a
            # palindrome
            if (table[i + 1][j - 1] and
                      st[i] == st[j]) :
                table[i][j] = True
     
                if (k > maxLength) :
                    start = i
                    maxLength = k
            i = i + 1
        k = k + 1
    print "Longest palindrome substring is: ", printSubStr(st, start,
                                               start + maxLength - 1)
 
    return maxLength # return length of LPS
 
 
# Driver program to test above functions
st = "forgeeksskeegfor"
l = longestPalSubstr(st)
print "Length is:", l
 
# This code is contributed by Nikita Tiwari.

C#

// C# Solution
using System;
 
class GFG {
 
    // A utility function to print a
    // substring str[low...( high - (low+1))]
    static void printSubStr(string str, int low,
                            int high)
    {
        Console.WriteLine(str.Substring(low,
                                        high - low + 1));
    }
 
    // This function prints the longest
    // palindrome substring of str[].
    // It also returns the length of the
    // longest palindrome
    static int longestPalSubstr(string str)
    {
 
        // Get length of input string
        int n = str.Length;
 
        // Table[i, j] will be false if substring
        // str[i..j] is not palindrome. Else
        // table[i, j] will be true
        bool[, ] table = new bool[n, n];
 
        // All substrings of length 1 are palindromes
        int maxLength = 1;
        for (int i = 0; i < n; ++i)
            table[i, i] = true;
 
        // Check for sub-string of length 2.
        int start = 0;
 
        for (int i = 0; i < n - 1; ++i) {
            if (str[i] == str[i + 1]) {
                table[i, i + 1] = true;
                start = i;
                maxLength = 2;
            }
        }
 
        // Check for lengths greater than 2.
        // k is length of substring
        for (int k = 3; k <= n; ++k) {
 
            // Fix the starting index
            for (int i = 0; i < n - k + 1; ++i) {
 
                // Get the ending index of substring from
                // starting index i and length k
                int j = i + k - 1;
 
                // Checking for sub-string from ith index
                // to jth index iff str.charAt(i+1) to
                // str.charAt(j-1) is a palindrome
                if (table[i + 1, j - 1] && str[i] == str[j]) {
                    table[i, j] = true;
                    if (k > maxLength) {
                        start = i;
                        maxLength = k;
                    }
                }
            }
        }
        Console.Write("Longest palindrome substring is: ");
        printSubStr(str, start, start + maxLength - 1);
 
        // Return length of LPS
        return maxLength;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        string str = "forgeeksskeegfor";
 
        Console.WriteLine("Length is: " + longestPalSubstr(str));
    }
}
 
// This code is contributed by SoumikMondal

输出:

Longest palindrome substring is: geeksskeeg
Length is: 10

复杂度分析:

  • 时间复杂度:O(n ^ 2)。
    需要两个嵌套的遍历。
  • 辅助空间:O(n ^ 2)。
    需要大小为n * n的矩阵来存储dp数组。