📌  相关文章
📜  范围 [L, R] 中偶数长度的最小回文子序列

📅  最后修改于: 2021-10-26 06:24:38             🧑  作者: Mango

给定一个大小为N的字符串和一些查询,任务是为每个查询在[L, R]范围内找到字典上最小的偶数长度回文子序列。如果不存在这样的回文子序列,则打印-1
例子:

方法:这个问题的主要观察是如果存在回文子序列,那么它的长度必须> 2 。因此所得到的子序列将是长度的字符串> 2以相同字符。选择那些具有大于1的频率更大的范围在[L,R]和打印字符两次字符中的最小字符。如果不存在这样的字符,则打印-1
下面是上述方法的实现:

C++
// C++ program to find lexicographically smallest
// palindromic subsequence of even length
 
#include 
using namespace std;
const int N = 100001;
 
// Frequency array for each character
int f[26][N];
 
// Preprocess the frequency array calculation
void precompute(string s, int n)
{
    // Frequency array to track each character
    // in position 'i'
    for (int i = 0; i < n; i++) {
        f[s[i] - 'a'][i]++;
    }
 
    // Calculating prefix sum
    // over this frequency array
    // to get frequency of a character
    // in a range [L, R].
    for (int i = 0; i < 26; i++) {
        for (int j = 1; j < n; j++) {
            f[i][j] += f[i][j - 1];
        }
    }
}
 
// Util function for palindromic subsequences
int palindromicSubsequencesUtil(int L, int R)
{
 
    int c, ok = 0;
 
    // Find frequency of all characters
    for (int i = 0; i < 26; i++) {
 
        // For each character
        // find it's frequency
        // in range [L, R]
        int cnt = f[i][R];
        if (L > 0)
            cnt -= f[i][L - 1];
 
        if (cnt > 1) {
 
            // If frequency in this range is > 1,
            // then we must take this character,
            // as it will give
            // lexicographically smallest one
            ok = 1;
            c = i;
            break;
        }
    }
 
    // There is no character
    // in range [L, R] such
    // that it's frequency is > 1.
    if (ok == 0) {
 
        return -1;
    }
 
    // Return the character's value
    return c;
}
 
// Function to find lexicographically smallest
// palindromic subsequence of even length
void palindromicSubsequences(int Q[][2], int l)
{
    for (int i = 0; i < l; i++) {
 
        // Find in the palindromic subsequences
        int x
            = palindromicSubsequencesUtil(
                Q[i][0], Q[i][1]);
 
        // No such subsequence exists
        if (x == -1) {
            cout << -1 << "\n";
        }
        else {
            char c = 'a' + x;
            cout << c << c << "\n";
        }
    }
}
 
// Driver Code
int main()
{
    string str = "dbdeke";
    int Q[][2] = { { 0, 5 },
                   { 1, 5 },
                   { 1, 3 } };
    int n = str.size();
    int l = sizeof(Q) / sizeof(Q[0]);
 
    // Function calls
    precompute(str, n);
 
    palindromicSubsequences(Q, l);
 
    return 0;
}


Java
// Java program to find lexicographically smallest
// palindromic subsequence of even length
import java.util.*;
 
class GFG{
static int N = 100001;
 
// Frequency array for each character
static int [][]f = new int[26][N];
 
// Preprocess the frequency array calculation
static void precompute(String s, int n)
{
    // Frequency array to track each character
    // in position 'i'
    for (int i = 0; i < n; i++)
    {
        f[s.charAt(i) - 'a'][i]++;
    }
 
    // Calculating prefix sum
    // over this frequency array
    // to get frequency of a character
    // in a range [L, R].
    for (int i = 0; i < 26; i++)
    {
        for (int j = 1; j < n; j++)
        {
            f[i][j] += f[i][j - 1];
        }
    }
}
 
// Util function for palindromic subsequences
static int palindromicSubsequencesUtil(int L, int R)
{
    int c = 0, ok = 0;
 
    // Find frequency of all characters
    for (int i = 0; i < 26; i++)
    {
 
        // For each character
        // find it's frequency
        // in range [L, R]
        int cnt = f[i][R];
        if (L > 0)
            cnt -= f[i][L - 1];
 
        if (cnt > 1)
        {
 
            // If frequency in this range is > 1,
            // then we must take this character,
            // as it will give
            // lexicographically smallest one
            ok = 1;
            c = i;
            break;
        }
    }
 
    // There is no character
    // in range [L, R] such
    // that it's frequency is > 1.
    if (ok == 0)
    {
        return -1;
    }
 
    // Return the character's value
    return c;
}
 
// Function to find lexicographically smallest
// palindromic subsequence of even length
static void palindromicSubsequences(int Q[][], int l)
{
    for (int i = 0; i < l; i++)
    {
 
        // Find in the palindromic subsequences
        int x = palindromicSubsequencesUtil(
                           Q[i][0], Q[i][1]);
 
        // No such subsequence exists
        if (x == -1)
        {
            System.out.print(-1 + "\n");
        }
        else
        {
            char c = (char) ('a' + x);
            System.out.print((char) c + "" +
                             (char) c + "\n");
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "dbdeke";
    int Q[][] = { { 0, 5 },
                  { 1, 5 },
                  { 1, 3 } };
    int n = str.length();
    int l = Q.length;
 
    // Function calls
    precompute(str, n);
 
    palindromicSubsequences(Q, l);
}
}
 
// This code is contributed by PrinciRaj1992


Python3
# Python3 program to find lexicographically
# smallest palindromic subsequence of even length
N = 100001
 
# Frequency array for each character
f = [[ 0 for x in range (N)]
         for y in range (26)]
 
# Preprocess the frequency array calculation
def precompute(s, n):
 
    # Frequency array to track each character
    # in position 'i'
    for i in range(n):
        f[ord(s[i]) - ord('a')][i] += 1
 
    # Calculating prefix sum
    # over this frequency array
    # to get frequency of a character
    # in a range [L, R].
    for i in range(26):
        for j in range(1, n):
            f[i][j] += f[i][j - 1]
 
# Util function for palindromic subsequences
def palindromicSubsequencesUtil(L, R):
 
    ok = 0
 
    # Find frequency of all characters
    for i in range(26):
 
        # For each character
        # find it's frequency
        # in range [L, R]
        cnt = f[i][R]
        if (L > 0):
            cnt -= f[i][L - 1]
 
        if (cnt > 1):
 
            # If frequency in this range is > 1,
            # then we must take this character,
            # as it will give
            # lexicographically smallest one
            ok = 1
            c = i
            break
         
    # There is no character
    # in range [L, R] such
    # that it's frequency is > 1.
    if (ok == 0):
        return -1
 
    # Return the character's value
    return c
 
# Function to find lexicographically smallest
# palindromic subsequence of even length
def palindromicSubsequences(Q, l):
 
    for i in range(l):
 
        # Find in the palindromic subsequences
        x = palindromicSubsequencesUtil(Q[i][0],
                                        Q[i][1])
 
        # No such subsequence exists
        if (x == -1):
            print(-1)
         
        else :
            c = ord('a') + x
            print(2 * chr(c))
 
# Driver Code
if __name__ == "__main__":
 
    st = "dbdeke"
    Q = [ [ 0, 5 ],
          [ 1, 5 ],
          [ 1, 3 ] ]
           
    n = len(st)
    l = len(Q)
 
    # Function calls
    precompute(st, n)
 
    palindromicSubsequences(Q, l)
 
# This code is contributed by chitranayal


C#
// C# program to find lexicographically smallest
// palindromic subsequence of even length
using System;
 
class GFG{
     
static int N = 100001;
 
// Frequency array for each character
static int [,]f = new int[26, N];
 
// Preprocess the frequency array calculation
static void precompute(String s, int n)
{
     
    // Frequency array to track each character
    // in position 'i'
    for(int i = 0; i < n; i++)
    {
        f[s[i] - 'a', i]++;
    }
 
    // Calculating prefix sum
    // over this frequency array
    // to get frequency of a character
    // in a range [L, R].
    for(int i = 0; i < 26; i++)
    {
        for(int j = 1; j < n; j++)
        {
            f[i, j] += f[i, j - 1];
        }
    }
}
 
// Util function for palindromic subsequences
static int palindromicSubsequencesUtil(int L, int R)
{
    int c = 0, ok = 0;
 
    // Find frequency of all characters
    for(int i = 0; i < 26; i++)
    {
 
        // For each character
        // find it's frequency
        // in range [L, R]
        int cnt = f[i, R];
        if (L > 0)
            cnt -= f[i, L - 1];
 
        if (cnt > 1)
        {
 
            // If frequency in this range is > 1,
            // then we must take this character,
            // as it will give
            // lexicographically smallest one
            ok = 1;
            c = i;
            break;
        }
    }
 
    // There is no character
    // in range [L, R] such
    // that it's frequency is > 1.
    if (ok == 0)
    {
        return -1;
    }
 
    // Return the character's value
    return c;
}
 
// Function to find lexicographically smallest
// palindromic subsequence of even length
static void palindromicSubsequences(int [,]Q, int l)
{
    for(int i = 0; i < l; i++)
    {
         
        // Find in the palindromic subsequences
        int x = palindromicSubsequencesUtil(Q[i, 0],
                                            Q[i, 1]);
 
        // No such subsequence exists
        if (x == -1)
        {
            Console.Write(-1 + "\n");
        }
        else
        {
            char c = (char)('a' + x);
            Console.Write((char) c + "" +
                          (char) c + "\n");
        }
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    String str = "dbdeke";
    int [,]Q = { { 0, 5 },
                 { 1, 5 },
                 { 1, 3 } };
    int n = str.Length;
    int l = Q.GetLength(0);
 
    // Function calls
    precompute(str, n);
 
    palindromicSubsequences(Q, l);
}
}
 
// This code is contributed by amal kumar choubey


Javascript


输出:
dd
ee
-1

时间复杂度: O(26 * N + 26 * Q),其中 N 是字符串的长度

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