最长回文子串

96 阅读9分钟

最长回文子串

给定一个字符串 str,任务是找到最长的回文子串。

例子:

输入:str = “forgeeksskeegfor”
输出:“geeksskeeg”
解释:有几个可能的回文子串,如“kssk”、“ss”、“eeksskee”等。但子串“geeksskeeg”是其中最长的。

输入:str =Geeks
输出:“ee”

暴力解法:

检查每个子串是否是回文,并不断更新迄今为止找到的最长回文子串。

请按照下面提到的步骤来实现这个想法:

  • 生成所有子串。
    • 对于每个子串,检查它是否是回文。
    • 如果子串是回文子串,则根据目前找到的最长回文子串更新结果。

下面是上述方法的实现:

C++

// A C++ solution for longest palindrome
 
#include <bits/stdc++.h>
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;
}

C

#include <stdio.h>
#include <string.h>
 
// Function to print a substring str[low..high]
void printSubStr(const char* str, int low, int high)
{
    for (int i = low; i <= high; ++i)
        printf("%c", str[i]);
}
 
// This function prints the longest palindrome substring
// It also returns the length of the longest palindrome
int longestPalSubstr(const char* str)
{
    // Get length of input string
    int n = strlen(str);
 
    // 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 < n; i++) {
        for (int j = i; j < n; 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;
            }
        }
    }
 
    printf("Longest palindrome substring is: ");
    printSubStr(str, start, start + maxLength - 1);
    printf("\n");
 
    // Return length of LPS
    return maxLength;
}
 
// Driver Code
int main()
{
    const char* str = "forgeeksskeegfor";
    printf("Length is: %d\n", 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));
    }
}
 

Python

# A Python3 solution for longest palindrome
 
 
# Function to print a 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))
 

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));
    }
}
 

Javascript

// A Javascript solution for longest palindrome
 
// Function to print a subString str[low..high]
function printSubStr(str,low,high)
{
    for (let i = low; i <= high; ++i)
        console.log(str[i]);
}
 
// This function prints the
// longest palindrome subString
// It also returns the length
// of the longest palindrome
function longestPalSubstr(str)
{
    // Get length of input String
    let n = str.length;
  
    // All subStrings of length 1
    // are palindromes
    let maxLength = 1, start = 0;
  
    // Nested loop to mark start and end index
    for (let i = 0; i < str.length; i++) {
        for (let j = i; j < str.length; j++) {
            let flag = 1;
  
            // Check palindrome
            for (let 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.log("Longest palindrome substring is: ");
    printSubStr(str, start, start + maxLength - 1);
  
    // Return length of LPS
    return maxLength;
}
 
// Driver Code
let str = "forgeeksskeegfor";
console.log("Length is: "
         + longestPalSubstr(str));
 

输出

Longest palindrome substring is: geeksskeeg
Length is: 10

复杂度分析:

  • 时间复杂度:O(N^3)。在此方法中需要三个嵌套循环来查找最长的回文子串。
  • 辅助复杂度:O(1)。因为不需要额外的空间。

从中心扩展:

LPS 的长度可以是偶数或奇数。因此,我们的想法是遍历输入字符串,并针对每个字符检查该字符是否可以是奇数长度或偶数长度的回文子串的中心。

请按照下面提到的步骤来实现这个想法:

  • 使用两个指针,low 和 hi,分别表示当前找到的回文子串的左端和右端。
  • 然后检查str[low]和str[hi]处的字符是否相同。
    • 如果是,则通过递减 low 并递增 hi 来向左和向右扩展子字符串。
    • 继续此过程,直到 str[low] 和 str[hi] 处的字符不相等或索引到达边界。
  • 如果当前回文子串的长度大于最大长度,则更新最大长度。

下面是上述想法的实现。

C++

// C++ code to implement the above idea
 
#include <bits/stdc++.h>
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];
}
 
// Function to find the longest palindromic substring
int longestPalSubstr(string s)
{
    int n = s.length();
    int start = 0, end = 1;
    int low, hi;
 
    // Traverse the input string
    for (int i = 0; i < n; i++) {
 
        // Find longest palindromic substring of even size
        low = i - 1;
        hi = i;
 
        // Expand substring while it is palindrome
        // and in bounds
        while (low >= 0 && hi < n && s[low] == s[hi]) {
 
            // Update maximum length and starting index
            if (hi - low + 1 > end) {
                start = low;
                end = hi - low + 1;
            }
            low--;
            hi++;
        }
 
        // Find longest palindromic substring of odd size
        low = i - 1;
        hi = i + 1;
 
        // Expand substring while it is palindrome
        // and in bounds
        while (low >= 0 && hi < n && s[low] == s[hi]) {
 
            // Update maximum length and starting index
            if (hi - low + 1 > end) {
                start = low;
                end = hi - low + 1;
               
            }
               low--;
            hi++;
        }
    }
 
    // Print the longest palindromic substring
    cout << "Longest palindrome substring is: ";
    printSubStr(s, start, start + end - 1);
 
    // Return output length
    return end;
}
 
// Driver code
int main()
{
    string str = "forgeeksskeegfor";
 
    // Function call
    cout << "\nLength is: " << longestPalSubstr(str);
    return 0;
}
 

C

#include <stdio.h>
#include <string.h>
 
// Function to print a substring str[low..high]
void printSubStr(char str[], int low, int high)
{
    for (int i = low; i <= high; ++i)
        printf("%c", str[i]);
}
 
// Function to find the longest palindromic substring
int longestPalSubstr(char s[])
{
    int n = strlen(s);
    int start = 0, end = 1;
    int low, hi;
 
    // Traverse the input string
    for (int i = 0; i < n; i++) {
 
        // Find longest palindromic substring of even size
        low = i - 1;
        hi = i;
 
        // Expand substring while it is palindrome
        // and in bounds
        while (low >= 0 && hi < n && s[low] == s[hi]) {
 
            // Update maximum length and starting index
            if (hi - low + 1 > end) {
                start = low;
                end = hi - low + 1;
            }
            low--;
            hi++;
        }
 
        // Find longest palindromic substring of odd size
        low = i - 1;
        hi = i + 1;
 
        // Expand substring while it is palindrome
        // and in bounds
        while (low >= 0 && hi < n && s[low] == s[hi]) {
 
            // Update maximum length and starting index
            if (hi - low + 1 > end) {
                start = low;
                end = hi - low + 1;
            }
            low--;
            hi++;
        }
    }
 
    // Print the longest palindromic substring
    printf("Longest palindrome substring is: ");
    printSubStr(s, start, start + end - 1);
 
    // Return output length
    return end;
}
 
// Driver code
int main()
{
    char str[] = "forgeeksskeegfor";
 
    // Function call
    printf("\nLength is: %d", longestPalSubstr(str));
    return 0;
}

Java

class LongestPalinSubstring {
    // 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));
        System.out.println();
    }
 
    // Function to find the longest palindromic substring
    static int longestPalSubstr(String s) {
        int n = s.length();
        int start = 0, end = 1;
        int low, hi;
 
        // Traverse the input string
        for (int i = 0; i < n; i++) {
 
            // Find longest palindromic substring of even size
            low = i - 1;
            hi = i;
 
            // Expand substring while it is palindrome and in bounds
            while (low >= 0 && hi < n && s.charAt(low) == s.charAt(hi)) {
 
                // Update maximum length and starting index
                if (hi - low + 1 > end) {
                    start = low;
                    end = hi - low + 1;
                }
                low--;
                hi++;
            }
 
            // Find longest palindromic substring of odd size
            low = i - 1;
            hi = i + 1;
 
            // Expand substring while it is palindrome and in bounds
            while (low >= 0 && hi < n && s.charAt(low) == s.charAt(hi)) {
 
                // Update maximum length and starting index
                if (hi - low + 1 > end) {
                    start = low;
                    end = hi - low + 1;
                }
                low--;
                hi++;
            }
        }
 
        // Print the longest palindromic substring
        System.out.print("Longest palindrome substring is: ");
        printSubStr(s, start, start + end - 1);
 
        // Return output length
        return end;
    }
 
    // Driver code
    public static void main(String[] args) {
        String s = "forgeeksskeegfor";
        int length = longestPalSubstr(s);
        System.out.println("Length: " + length);
    }
}

Python

def printSubStr(s, low, high):
    for i in range(low, high + 1):
        print(s[i], end="")
    print()
 
def longestPalSubstr(s):
    n = len(s)
    start = 0
    end = 1
 
    for i in range(n):
        # Find the longest palindromic substring of even length
        low = i - 1
        hi = i
 
        while low >= 0 and hi < n and s[low] == s[hi]:
            if hi - low + 1 > end:
                start = low
                end = hi - low + 1
            low -= 1
            hi += 1
 
        # Find the longest palindromic substring of odd length
        low = i - 1
        hi = i + 1
 
        while low >= 0 and hi < n and s[low] == s[hi]:
            if hi - low + 1 > end:
                start = low
                end = hi - low + 1
            low -= 1
            hi += 1
 
    # Print the longest palindromic substring
    print("Longest palindrome substring is: ", end="")
    printSubStr(s, start, start + end - 1)
 
    # Return the length of the longest palindromic substring
    return end
 
# Driver Code:
if __name__=='__main__':
    s="forgeeksskeegfor"
    length = longestPalSubstr(s)
    print("Length:", length)
     

C#

using System;
 
class GFG {
    // Function to print a substring
    static void PrintSubStr(string s, int low, int high)
    {
        for (int i = low; i <= high; i++) {
            Console.Write(s[i]);
        }
        Console.WriteLine();
    }
 
    // Function to find the longest palindromic substring
    static int LongestPalSubstr(string s)
    {
        int n = s.Length;
        int start = 0;
        int end = 1;
 
        for (int i = 0; i < n; i++) {
            // Find the longest palindromic substring of
            // even length
            int low = i - 1;
            int hi = i;
 
            while (low >= 0 && hi < n && s[low] == s[hi]) {
                if (hi - low + 1 > end) {
                    start = low;
                    end = hi - low + 1;
                }
                low--;
                hi++;
            }
 
            // Find the longest palindromic substring of odd
            // length
            low = i - 1;
            hi = i + 1;
 
            while (low >= 0 && hi < n && s[low] == s[hi]) {
                if (hi - low + 1 > end) {
                    start = low;
                    end = hi - low + 1;
                }
                low--;
                hi++;
            }
        }
 
        // Print the longest palindromic substring
        Console.Write("Longest palindrome substring is: ");
        PrintSubStr(s, start, start + end - 1);
 
        // Return the length of the longest palindromic
        // substring
        return end;
    }
 
    // Driver Code:
    static void Main()
    {
        string s = "forgeeksskeegfor";
        int length = LongestPalSubstr(s);
        Console.WriteLine("Length: " + length);
    }
}

Javascript

// Function to print a substring str[low..high]
function printSubStr(str, low, high) {
    for (let i = low; i <= high; ++i) {
        console.log(str[i]);
    }
}
 
// Function to find the longest palindromic substring
function longestPalSubstr(s) {
    const n = s.length;
    let start = 0, end = 1;
    let low, hi;
 
    // Traverse the input string
    for (let i = 0; i < n; i++) {
 
        // Find the longest palindromic substring of even size
        low = i - 1;
        hi = i;
 
        // Expand substring while it is a palindrome
        // and in bounds
        while (low >= 0 && hi < n && s[low] === s[hi]) {
 
            // Update the maximum length and starting index
            if (hi - low + 1 > end) {
                start = low;
                end = hi - low + 1;
            }
            low--;
            hi++;
        }
 
        // Find the longest palindromic substring of odd size
        low = i - 1;
        hi = i + 1;
 
        // Expand substring while it is a palindrome
        // and in bounds
        while (low >= 0 && hi < n && s[low] === s[hi]) {
 
            // Update the maximum length and starting index
            if (hi - low + 1 > end) {
                start = low;
                end = hi - low + 1;
            }
            low--;
            hi++;
        }
    }
 
    // Print the longest palindromic substring
    console.log("Longest palindrome substring is: ");
    printSubStr(s, start, start + end - 1);
 
    // Return the output length
    return end;
}
 
 
    const str = "forgeeksskeegfor";
 
    
    console.log("\nLength is: " + longestPalSubstr(str));

输出

Longest palindrome substring is: geeksskeeg
Length is: 10

时间复杂度:O(N^2),其中N是输入字符串的长度
辅助空间:O(1),不使用额外空间。