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

📅  最后修改于: 2021-04-22 09:59:56             🧑  作者: 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


输出:
dd
ee
-1

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