📜  索引范围内回文子串的计数

📅  最后修改于: 2021-09-17 07:10:26             🧑  作者: Mango

给定一个除此之外的小字母字符的字符串str ,我们将以索引元组的形式给出该字符串的许多子字符串。我们需要找出给定子串范围内回文子串的数量。
例子:

Input : String str = "xyaabax"
           Range1 = (3, 5)   
           Range2 = (2, 3) 
Output : 4
         3
For Range1,  substring is "aba"
Count of palindromic substring in "aba" is 
four : "a", "b", "aba", "a"
For Range2,  substring is "aa"
Count of palindromic substring in "aa" is 
3 : "a", "a", "aa"

先决条件:计算字符串中的所有回文子字符串
我们可以使用动态规划来解决这个问题。首先我们将创建一个二维数组 isPalin,如果字符串(i..j) 是回文,则 isPalin[i][j] 将为 1,否则为 0。构造 isPalin 后,我们将构造另一个二维数组 dp, dp[i ][j] 将告诉字符串(i..j) 中回文子串的计数
现在我们可以写出 isPalin 和 dp 值之间的关系,如下所示,

// isPalin[i][j] will be 1 if ith and jth characters 
// are equal and mid substring str(i+1..j-1) is also
// a palindrome
isPalin[i][j] = (str[i] == str[j]) and 
                (isPalin[i + 1][j – 1])
              
// Similar to set theory we can write the relation among
// dp values as,
// dp[i][j] will be addition of number of palindromes from 
// i to j-1 and i+1 to j  subtracting palindromes from i+1
// to j-1 because they are counted twice once in dp[i][j-1] 
// and then in dp[i + 1][j] plus 1 if str(i..j) is also a
// palindrome
dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1] + 
                                     isPalin[i][j];

解决方案的总时间复杂度为 O(length ^ 2),用于构建 dp 数组,然后每个查询为 O(1)。

C++
// C++ program to query number of palindromic
// substrings of a string in a range
#include 
using namespace std;
#define M 50
 
// Utility method to construct the dp array
void constructDP(int dp[M][M], string str)
{
    int l = str.length();
 
    // declare 2D array isPalin, isPalin[i][j] will
    // be 1 if str(i..j) is palindrome
    int isPalin[l + 1][l + 1];
 
    // initialize dp and isPalin array by zeros
    for (int i = 0; i <= l; i++) {
        for (int j = 0; j <= l; j++) {
            isPalin[i][j] = dp[i][j] = 0;
        }
    }
 
    // loop for starting index of range
    for (int i = l - 1; i >= 0; i--) {
 
        // initialize value for one character strings as 1
        isPalin[i][i] = 1;
        dp[i][i] = 1;
 
        // loop for ending index of range
        for (int j = i + 1; j < l; j++) {
 
            /* isPalin[i][j] will be 1 if ith and
               jth characters are equal and mid
               substring str(i+1..j-1) is also a
               palindrome             */
            isPalin[i][j] = (str[i] == str[j] && (i + 1 > j - 1 || isPalin[i + 1][j - 1]));
 
            /* dp[i][j] will be addition of number
               of palindromes from i to j-1 and i+1
               to j subtracting palindromes from i+1
               to j-1 (as counted twice) plus 1 if
               str(i..j) is also a palindrome */
            dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1] + isPalin[i][j];
        }
    }
}
 
// method returns count of palindromic substring in range (l, r)
int countOfPalindromeInRange(int dp[M][M], int l, int r)
{
    return dp[l][r];
}
 
// Driver code to test above methods
int main()
{
    string str = "xyaabax";
 
    int dp[M][M];
    constructDP(dp, str);
 
    int l = 3;
    int r = 5;
 
    cout << countOfPalindromeInRange(dp, l, r);
    return 0;
}


Java
// Java program  to query number of palindromic
// substrings of a string in a range
import java.io.*;
 
class GFG {
    // Function to construct the dp array
    static void constructDp(int dp[][], String str)
    {
        int l = str.length();
 
        // declare 2D array isPalin, isPalin[i][j] will
        // be 1 if str(i..j) is palindrome
        int[][] isPalin = new int[l + 1][l + 1];
 
        // initialize dp and isPalin array by zeros
        for (int i = 0; i <= l; i++) {
            for (int j = 0; j <= l; j++) {
                isPalin[i][j] = dp[i][j] = 0;
            }
        }
 
        // loop for starting index of range
        for (int i = l - 1; i >= 0; i--) {
            // initialize value for one character strings as 1
            isPalin[i][i] = 1;
            dp[i][i] = 1;
 
            // loop for ending index of range
            for (int j = i + 1; j < l; j++) {
                /* isPalin[i][j] will be 1 if ith and
                jth characters are equal and mid
                substring str(i+1..j-1) is also a
                palindrome             */
                isPalin[i][j] = (str.charAt(i) == str.charAt(j) && (i + 1 > j - 1 || (isPalin[i + 1][j - 1]) != 0)) ? 1 : 0;
 
                /* dp[i][j] will be addition of number
                of palindromes from i to j-1 and i+1
                to j subtracting palindromes from i+1
                to j-1 (as counted twice) plus 1 if
                str(i..j) is also a palindrome */
                dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1] + isPalin[i][j];
            }
        }
    }
 
    // method returns count of palindromic substring in range (l, r)
    static int countOfPalindromeInRange(int dp[][], int l, int r)
    {
        return dp[l][r];
    }
 
    // driver program
    public static void main(String args[])
    {
        int MAX = 50;
        String str = "xyaabax";
        int[][] dp = new int[MAX][MAX];
        constructDp(dp, str);
 
        int l = 3;
        int r = 5;
        System.out.println(countOfPalindromeInRange(dp, l, r));
    }
}
 
// Contributed by Pramod Kumar


Python3
# Python3 program to query the number of
# palindromic substrings of a string in a range
M = 50
 
# Utility method to construct the dp array
def constructDP(dp, string):
 
    l = len(string)
 
    # declare 2D array isPalin, isPalin[i][j]
    # will be 1 if str(i..j) is palindrome
    # and initialize it with zero
    isPalin = [[0 for i in range(l + 1)]
                  for j in range(l + 1)]
 
    # loop for starting index of range
    for i in range(l - 1, -1, -1):
 
        # initialize value for one
        # character strings as 1
        isPalin[i][i], dp[i][i] = 1, 1
 
        # loop for ending index of range
        for j in range(i + 1, l):
 
            # isPalin[i][j] will be 1 if ith and jth
            # characters are equal and mid substring
            # str(i+1..j-1) is also a palindrome
            isPalin[i][j] = (string[i] == string[j] and
                            (i + 1 > j - 1 or isPalin[i + 1][j - 1]))
 
            # dp[i][j] will be addition of number
            # of palindromes from i to j-1 and i+1
            # to j subtracting palindromes from i+1
            # to j-1 (as counted twice) plus 1 if
            # str(i..j) is also a palindrome
            dp[i][j] = (dp[i][j - 1] + dp[i + 1][j] -
                        dp[i + 1][j - 1] + isPalin[i][j])
 
# Method returns count of palindromic
# substring in range (l, r)
def countOfPalindromeInRange(dp, l, r):
    return dp[l][r]
 
# Driver code
if __name__ == "__main__":
 
    string = "xyaabax"
    dp = [[0 for i in range(M)]
             for j in range(M)]
     
    constructDP(dp, string)
 
    l, r = 3, 5
    print(countOfPalindromeInRange(dp, l, r))
 
# This code is contributed by Rituraj Jain


C#
// C# program to query number of palindromic
// substrings of a string in a range
using System;
 
class GFG {
     
    // Function to construct the dp array
    static void constructDp(int[, ] dp, string str)
    {
        int l = str.Length;
 
        // declare 2D array isPalin, isPalin[i][j]
        // will be 1 if str(i..j) is palindrome
        int[, ] isPalin = new int[l + 1, l + 1];
 
        // initialize dp and isPalin array by zeros
        for (int i = 0; i <= l; i++) {
            for (int j = 0; j <= l; j++) {
                isPalin[i, j] = dp[i, j] = 0;
            }
        }
 
        // loop for starting index of range
        for (int i = l - 1; i >= 0; i--) {
             
            // initialize value for one
            // character strings as 1
            isPalin[i, i] = 1;
            dp[i, i] = 1;
 
            // loop for ending index of range
            for (int j = i + 1; j < l; j++) {
                 
                /* isPalin[i][j] will be 1 if ith and
                jth characters are equal and mid
                substring str(i+1..j-1) is also a
                palindrome*/
                isPalin[i, j] = (str[i] == str[j] && (i + 1 > j - 1 ||
                                (isPalin[i + 1, j - 1]) != 0)) ? 1 : 0;
 
                /* dp[i][j] will be addition of number
                of palindromes from i to j-1 and i+1
                to j subtracting palindromes from i+1
                to j-1 (as counted twice) plus 1 if
                str(i..j) is also a palindrome */
                dp[i, j] = dp[i, j - 1] + dp[i + 1, j] -
                           dp[i + 1, j - 1] + isPalin[i, j];
            }
        }
    }
 
    // method returns count of palindromic
    // substring in range (l, r)
    static int countOfPalindromeInRange(int[, ] dp,
                                      int l, int r)
    {
        return dp[l, r];
    }
 
    // driver program
    public static void Main()
    {
        int MAX = 50;
        string str = "xyaabax";
        int[, ] dp = new int[MAX, MAX];
        constructDp(dp, str);
 
        int l = 3;
        int r = 5;
        Console.WriteLine(countOfPalindromeInRange(dp, l, r));
    }
}
 
// This code is contributed by vt_m.


PHP
= 0; $i--)
    {
 
        // initialize value for one character
        // strings as 1
        $isPalin[$i][$i] = 1;
        $dp[$i][$i] = 1;
 
        // loop for ending index of range
        for ($j = $i + 1; $j < $l; $j++)
        {
 
            /* isPalin[i][j] will be 1 if ith and
            jth characters are equal and mid
            substring str(i+1..j-1) is also a
            palindrome         */
            $isPalin[$i][$j] = ($str[$i] == $str[$j] &&
                               ($i + 1 > $j - 1 ||
                                $isPalin[$i + 1][$j - 1]));
 
            /* dp[i][j] will be addition of number
            of palindromes from i to j-1 and i+1
            to j subtracting palindromes from i+1
            to j-1 (as counted twice) plus 1 if
            str(i..j) is also a palindrome */
            $dp[$i][$j] = $dp[$i][$j - 1] + $dp[$i + 1][$j] -
                          $dp[$i + 1][$j - 1] + $isPalin[$i][$j];
        }
    }
    return $dp ;
}
 
// method returns count of palindromic
// substring in range (l, r)
function countOfPalindromeInRange($dp, $l, $r)
{
    return $dp[$l][$r];
}
 
// Driver code
$str = "xyaabax";
 
$dp = array(array());
 
for($i = 0; $i < $GLOBALS['M']; $i++ )
    for($j = 0; $j < $GLOBALS['M']; $j++)
        $dp[$i][$j] = 0;
         
$dp = constructDP($dp, $str);
 
$l = 3;
$r = 5;
 
echo countOfPalindromeInRange($dp, $l, $r);
 
// This code is contributed by Ryuga
?>


Javascript


输出:

4

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程