📌  相关文章
📜  每个中心周围奇数长度回文子序列的总数

📅  最后修改于: 2021-09-22 10:04:24             🧑  作者: Mango

给定一个字符串str ,任务是找到 str 周围以str[i]为中心的奇数长度回文子序列的数量,即每个索引都将被一一视为中心。
例子:

方法:我们将使用动态规划来解决这个问题。让我们将字符串str 的长度表示为N 。现在,让dp[i][j]表示从0i – 1的回文子序列的数量和从jN – 1的回文子序列的数量。
lenij之间的距离。对于每个长度len ,我们将修复我们的ij ,并检查字符str[i]str[j]是否相等。然后根据它,我们将进行 dp 转换。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to find the total palindromic
// odd length sub-sequences
void solve(string& s)
{
    int n = s.length();
 
    // dp array to store the number of palindromic
    // subsequences for 0 to i-1 and j+1 to n-1
    int dp[n][n];
    memset(dp, 0, sizeof dp);
 
    // We will start with the largest
    // distance between i and j
    for (int len = n - 1; len >= 0; --len) {
 
        // For each len, we fix our i
        for (int i = 0; i + len < n; ++i) {
 
            // For this i we will find our j
            int j = i + len;
 
            // Base cases
            if (i == 0 and j == n - 1) {
                if (s[i] == s[j])
                    dp[i][j] = 2;
                else if (s[i] != s[j])
                    dp[i][j] = 1;
            }
            else {
                if (s[i] == s[j]) {
 
                    // If the characters are equal
                    // then look for out of bound index
                    if (i - 1 >= 0) {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1) {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 < 0 or j + 1 >= n) {
 
                        // We have only 1 way that is to
                        // just pick these characters
                        dp[i][j] += 1;
                    }
                }
                else if (s[i] != s[j]) {
 
                    // If the characters are not equal
                    if (i - 1 >= 0) {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1) {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 >= 0 and j + 1 <= n - 1) {
 
                        // Subtract it as we have
                        // counted it twice
                        dp[i][j] -= dp[i - 1][j + 1];
                    }
                }
            }
        }
    }
    vector ways;
    for (int i = 0; i < n; ++i) {
        if (i == 0 or i == n - 1) {
 
            // We have just 1 palindrome
            // sequence of length 1
            ways.push_back(1);
        }
        else {
 
            // Else total ways would be sum of dp[i-1][i+1],
            // that is number of palindrome sub-sequences
            // from 1 to i-1 + number of palindrome
            // sub-sequences from i+1 to n-1
            int total = dp[i - 1][i + 1];
            ways.push_back(total);
        }
    }
    for (int i = 0; i < ways.size(); ++i) {
        cout << ways[i] << " ";
    }
}
 
// Driver code
int main()
{
    string s = "xyxyx";
    solve(s);
 
    return 0;
}


Java
// Java implementation of above approach
import java.util.*;
 
class GFG
{
 
// Function to find the total palindromic
// odd length sub-sequences
static void solve(char[] s)
{
    int n = s.length;
 
    // dp array to store the number of palindromic
    // subsequences for 0 to i-1 and j+1 to n-1
    int [][]dp = new int[n][n];
 
    // We will start with the largest
    // distance between i and j
    for (int len = n - 1; len >= 0; --len)
    {
 
        // For each len, we fix our i
        for (int i = 0; i + len < n; ++i)
        {
 
            // For this i we will find our j
            int j = i + len;
 
            // Base cases
            if (i == 0 && j == n - 1)
            {
                if (s[i] == s[j])
                    dp[i][j] = 2;
                else if (s[i] != s[j])
                    dp[i][j] = 1;
            }
            else
            {
                if (s[i] == s[j])
                {
 
                    // If the characters are equal
                    // then look for out of bound index
                    if (i - 1 >= 0)
                    {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1)
                    {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 < 0 || j + 1 >= n)
                    {
 
                        // We have only 1 way that is to
                        // just pick these characters
                        dp[i][j] += 1;
                    }
                }
                else if (s[i] != s[j])
                {
 
                    // If the characters are not equal
                    if (i - 1 >= 0)
                    {
                        dp[i][j] += dp[i - 1][j];
                    }
                    if (j + 1 <= n - 1)
                    {
                        dp[i][j] += dp[i][j + 1];
                    }
                    if (i - 1 >= 0 && j + 1 <= n - 1)
                    {
 
                        // Subtract it as we have
                        // counted it twice
                        dp[i][j] -= dp[i - 1][j + 1];
                    }
                }
            }
        }
    }
     
    Vector ways = new Vector<>();
    for (int i = 0; i < n; ++i)
    {
        if (i == 0 || i == n - 1)
        {
 
            // We have just 1 palindrome
            // sequence of length 1
            ways.add(1);
        }
        else
        {
 
            // Else total ways would be sum of dp[i-1][i+1],
            // that is number of palindrome sub-sequences
            // from 1 to i-1 + number of palindrome
            // sub-sequences from i+1 to n-1
            int total = dp[i - 1][i + 1];
            ways.add(total);
        }
    }
    for (int i = 0; i < ways.size(); ++i)
    {
        System.out.print(ways.get(i) + " ");
    }
}
 
// Driver code
public static void main(String[] args)
{
    char[] s = "xyxyx".toCharArray();
    solve(s);
}
}
 
// This code has been contributed by 29AjayKumar


Python3
# Function to find the total palindromic
# odd Length sub-sequences
def solve(s):
    n = len(s)
 
    # dp array to store the number of palindromic
    # subsequences for 0 to i-1 and j+1 to n-1
    dp=[[0 for i in range(n)] for i in range(n)]
 
    # We will start with the largest
    # distance between i and j
    for Len in range(n-1,-1,-1):
 
        # For each Len, we fix our i
        for i in range(n):
 
            if i + Len >= n:
                break
 
            # For this i we will find our j
            j = i + Len
 
            # Base cases
            if (i == 0 and j == n - 1):
                if (s[i] == s[j]):
                    dp[i][j] = 2
                elif (s[i] != s[j]):
                    dp[i][j] = 1
            else:
                if (s[i] == s[j]):
                    # If the characters are equal
                    # then look for out of bound index
                    if (i - 1 >= 0):
                        dp[i][j] += dp[i - 1][j]
 
                    if (j + 1 <= n - 1):
                        dp[i][j] += dp[i][j + 1]
 
                    if (i - 1 < 0 or j + 1 >= n):
 
                        # We have only 1 way that is to
                        # just pick these characters
                        dp[i][j] += 1
 
                elif (s[i] != s[j]):
 
                    # If the characters are not equal
                    if (i - 1 >= 0):
                        dp[i][j] += dp[i - 1][j]
 
                    if (j + 1 <= n - 1):
                        dp[i][j] += dp[i][j + 1]
 
                    if (i - 1 >= 0 and j + 1 <= n - 1):
 
                        # Subtract it as we have
                        # counted it twice
                        dp[i][j] -= dp[i - 1][j + 1]
 
    ways = []
    for i in range(n):
        if (i == 0 or i == n - 1):
 
            # We have just 1 palindrome
            # sequence of Length 1
            ways.append(1)
        else:
 
            # Else total ways would be sum of dp[i-1][i+1],
            # that is number of palindrome sub-sequences
            # from 1 to i-1 + number of palindrome
            # sub-sequences from i+1 to n-1
            total = dp[i - 1][i + 1]
            ways.append(total)
 
    for i in ways:
        print(i,end=" ")
 
# Driver code
 
s = "xyxyx"
solve(s)
 
# This code is contributed by mohit kumar 29


C#
// C# implementation of above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to find the total palindromic
    // odd length sub-sequences
    static void solve(char[] s)
    {
        int n = s.Length;
     
        // dp array to store the number of palindromic
        // subsequences for 0 to i-1 and j+1 to n-1
        int [,]dp = new int[n, n];
     
        // We will start with the largest
        // distance between i and j
        for (int len = n - 1; len >= 0; --len)
        {
     
            // For each len, we fix our i
            for (int i = 0; i + len < n; ++i)
            {
     
                // For this i we will find our j
                int j = i + len;
     
                // Base cases
                if (i == 0 && j == n - 1)
                {
                    if (s[i] == s[j])
                        dp[i, j] = 2;
                    else if (s[i] != s[j])
                        dp[i, j] = 1;
                }
                else
                {
                    if (s[i] == s[j])
                    {
     
                        // If the characters are equal
                        // then look for out of bound index
                        if (i - 1 >= 0)
                        {
                            dp[i, j] += dp[i - 1, j];
                        }
                        if (j + 1 <= n - 1)
                        {
                            dp[i, j] += dp[i, j + 1];
                        }
                        if (i - 1 < 0 || j + 1 >= n)
                        {
     
                            // We have only 1 way that is to
                            // just pick these characters
                            dp[i, j] += 1;
                        }
                    }
                    else if (s[i] != s[j])
                    {
     
                        // If the characters are not equal
                        if (i - 1 >= 0)
                        {
                            dp[i, j] += dp[i - 1, j];
                        }
                        if (j + 1 <= n - 1)
                        {
                            dp[i, j] += dp[i, j + 1];
                        }
                        if (i - 1 >= 0 && j + 1 <= n - 1)
                        {
     
                            // Subtract it as we have
                            // counted it twice
                            dp[i, j] -= dp[i - 1, j + 1];
                        }
                    }
                }
            }
        }
         
        List ways = new List();
 
        for (int i = 0; i < n; ++i)
        {
            if (i == 0 || i == n - 1)
            {
     
                // We have just 1 palindrome
                // sequence of length 1
                ways.Add(1);
            }
            else
            {
     
                // Else total ways would be sum of dp[i-1][i+1],
                // that is number of palindrome sub-sequences
                // from 1 to i-1 + number of palindrome
                // sub-sequences from i+1 to n-1
                int total = dp[i - 1,i + 1];
                ways.Add(total);
            }
        }
        for (int i = 0; i < ways.Capacity; ++i)
        {
            Console.Write(ways[i] + " ");
        }
    }
     
    // Driver code
    public static void Main()
    {
        char[] s = "xyxyx".ToCharArray();
        solve(s);
    }
}
 
// This code is contributed by AnkitRai01


输出:
1 3 4 3 1

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