📜  查询后缀中不同整数的数量

📅  最后修改于: 2021-04-22 02:23:17             🧑  作者: Mango

给定N个元素和Q个查询的数组,其中每个查询包含一个整数K。对于每个查询,任务是查找后缀中从K元素到N元素的不同整数的数量。

例子:

Input :
N=5, Q=3
arr[] = {2, 4, 6, 10, 2}
1
3
2
Output :
4
3
4

方法:
通过预计算从N-10的所有索引的解可以解决该问题。这个想法是在C++中使用unordered_set,因为set不允许重复的元素。

从末尾遍历数组并将当前元素添加到集合中,当前索引的答案将是集合的大小。因此,将存储在当前索引处的set大小存储在一个名为suffixCount的辅助数组中。

下面是上述方法的实现:

C++
// C++ program to find distinct
// elements in suffix
  
#include 
using namespace std;
  
// Function to answer queries for distinct
// count in Suffix
void printQueries(int n, int a[], int q, int qry[])
{
    // Set to keep the distinct elements
    unordered_set occ;
  
    int suffixCount[n + 1];
  
    // Precompute the answer for each suffix
    for (int i = n - 1; i >= 0; i--) {
        occ.insert(a[i]);
        suffixCount[i + 1] = occ.size();
    }
  
    // Print the precomputed answers
    for (int i = 0; i < q; i++)
        cout << suffixCount[qry[i]] << endl;
}
  
// Driver Code
int main()
{
    int n = 5, q = 3;
    int a[n] = { 2, 4, 6, 10, 2 };
    int qry[q] = { 1, 3, 2 };
  
    printQueries(n, a, q, qry);
  
    return 0;
}


Java
// Java program to find distinct
// elements in suffix
import java.util.*;
  
class GFG 
{
  
  
// Function to answer queries for distinct
// count in Suffix
static void printQueries(int n, int a[], int q, int qry[])
{
    // Set to keep the distinct elements
    HashSet occ = new HashSet<>();
  
    int []suffixCount = new int[n + 1];
  
    // Precompute the answer for each suffix
    for (int i = n - 1; i >= 0; i--) 
    {
        occ.add(a[i]);
        suffixCount[i + 1] = occ.size();
    }
  
    // Print the precomputed answers
    for (int i = 0; i < q; i++)
        System.out.println(suffixCount[qry[i]]);
}
  
// Driver Code
public static void main(String args[]) 
{
    int n = 5, q = 3;
    int a[] = { 2, 4, 6, 10, 2 };
    int qry[] = { 1, 3, 2 };
  
    printQueries(n, a, q, qry);
}
}
  
/* This code contributed by PrinciRaj1992 */


Python3
# Python3 program to find distinct
# elements in suffix
  
# Function to answer queries for distinct
# count in Suffix
def printQueries(n, a, q, qry):
  
    # Set to keep the distinct elements
    occ = dict()
  
    suffixCount = [0 for i in range(n + 1)]
  
    # Precompute the answer for each suffix
    for i in range(n - 1, -1, -1):
        occ[a[i]] = 1
        suffixCount[i + 1] = len(occ)
  
    # Print the precomputed answers
    for i in range(q):
        print(suffixCount[qry[i]])
  
# Driver Code
n = 5
q = 3
a = [2, 4, 6, 10, 2]
qry = [1, 3, 2]
  
printQueries(n, a, q, qry)
  
# This code is contributed by Mohit Kumar 29


C#
// C# program to find distinct 
// elements in suffix 
using System;
using System.Collections.Generic;
  
public class GFG 
{ 
  
  
// Function to answer queries for distinct 
// count in Suffix 
static void printQueries(int n, int []a, int q, int []qry) 
{ 
    // Set to keep the distinct elements 
    HashSet occ = new HashSet(); 
  
    int []suffixCount = new int[n + 1]; 
  
    // Precompute the answer for each suffix 
    for (int i = n - 1; i >= 0; i--) 
    { 
        occ.Add(a[i]); 
        suffixCount[i + 1] = occ.Count; 
    } 
  
    // Print the precomputed answers 
    for (int i = 0; i < q; i++) 
        Console.WriteLine(suffixCount[qry[i]]); 
} 
  
// Driver Code 
public static void Main(String []args) 
{ 
    int n = 5, q = 3; 
    int []a = { 2, 4, 6, 10, 2 }; 
    int []qry = { 1, 3, 2 }; 
  
    printQueries(n, a, q, qry); 
} 
} 
  
// This code is contributed by Princi Singh


PHP
= 0; $i--)
    { 
        array_push($occ, $a[$i]); 
          
        # give array of distinct element
        $occ = array_unique($occ);
          
        $suffixCount[$i + 1] = sizeof($occ); 
    } 
      
      
    // Print the precomputed answers 
    for ($i = 0; $i < $q; $i++) 
        echo $suffixCount[$qry[$i]], "\n"; 
}
  
// Driver Code 
$n = 5;
$q = 3; 
$a = array(2, 4, 6, 10, 2); 
$qry = array(1, 3, 2); 
  
printQueries($n, $a, $q, $qry); 
  
// This code is contributed by Ryuga
?>


C++
// C++ implementation of the above approach.
#include 
  
#define MAX 100002
using namespace std;
  
// Function to print no of unique elements
// in specified suffix for each query.
void printUniqueElementsInSuffix(const int* arr,
                                 int n, const int* q, int m)
{
  
    // aux[i] stores no of unique elements in arr[i..n]
    int aux[MAX];
  
    // mark[i] = 1 if i has occurred in the suffix at least once.
    int mark[MAX];
    memset(mark, 0, sizeof(mark));
  
    // Initialization for the last element.
    aux[n - 1] = 1;
    mark[arr[n - 1]] = 1;
  
    for (int i = n - 2; i >= 0; i--) {
        if (mark[arr[i]] == 0) {
            aux[i] = aux[i + 1] + 1;
            mark[arr[i]] = 1;
        }
        else {
            aux[i] = aux[i + 1];
        }
    }
  
    for (int i = 0; i < m; i++) {
        cout << aux[q[i] - 1] << "\n";
    }
}
  
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int q[] = { 1, 3, 6 };
    int m = sizeof(q) / sizeof(q[0]);
    printUniqueElementsInSuffix(arr, n, q, m);
    return 0;
}


Java
// Java implementation of the above approach.
class GFG
{
      
static int MAX = 100002;
  
// Function to print no of unique elements
// in specified suffix for each query.
static void printUniqueElementsInSuffix(int[] arr,
                                int n, int[] q, int m)
{
  
    // aux[i] stores no of unique elements in arr[i..n]
    int []aux = new int[MAX];
  
    // mark[i] = 1 if i has occurred 
    // in the suffix at least once.
    int []mark = new int[MAX];
  
    // Initialization for the last element.
    aux[n - 1] = 1;
    mark[arr[n - 1]] = 1;
  
    for (int i = n - 2; i >= 0; i--) 
    {
        if (mark[arr[i]] == 0) 
        {
            aux[i] = aux[i + 1] + 1;
            mark[arr[i]] = 1;
        }
        else 
        {
            aux[i] = aux[i + 1];
        }
    }
  
    for (int i = 0; i < m; i++) 
    {
        System.out.println(aux[q[i] - 1] );
    }
}
  
// Driver code
public static void main(String[] args) 
{
  
    int arr[] = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
    int n = arr.length;
    int q[] = { 1, 3, 6 };
    int m = q.length;
    printUniqueElementsInSuffix(arr, n, q, m);
}
}
  
// This code is contributed by Princi Singh


Python3
# Python implementation of the above approach.
MAX = 100002;
  
# Function to prno of unique elements
# in specified suffix for each query.
def printUniqueElementsInSuffix(arr, n, q, m):
  
    # aux[i] stores no of unique elements in arr[i..n]
    aux = [0] * MAX;
  
    # mark[i] = 1 if i has occurred
    # in the suffix at least once.
    mark = [0] * MAX;
  
    # Initialization for the last element.
    aux[n - 1] = 1;
    mark[arr[n - 1]] = 1;
  
    for i in range(n - 2, -1, -1):
        if (mark[arr[i]] == 0):
            aux[i] = aux[i + 1] + 1;
            mark[arr[i]] = 1;
        else:
            aux[i] = aux[i + 1];
  
    for i in range(m):
        print(aux[q[i] - 1]);
  
# Driver code
if __name__ == '__main__':
    arr = [1, 2, 3, 4, 1, 2, 3, 4, 10000, 999];
    n = len(arr);
    q = [1, 3, 6];
    m = len(q);
    printUniqueElementsInSuffix(arr, n, q, m);
  
# This code is contributed by 29AjayKumar


C#
// C# implementation of the above approach.
using System;
  
class GFG
{
    static int MAX = 100002;
  
    // Function to print no of unique elements
    // in specified suffix for each query.
    static void printUniqueElementsInSuffix(int[] arr,
                                    int n, int[] q, int m)
    {
      
        // aux[i] stores no of unique elements in arr[i..n]
        int []aux = new int[MAX];
      
        // mark[i] = 1 if i has occurred 
        // in the suffix at least once.
        int []mark = new int[MAX];
      
        // Initialization for the last element.
        aux[n - 1] = 1;
        mark[arr[n - 1]] = 1;
      
        for (int i = n - 2; i >= 0; i--) 
        {
            if (mark[arr[i]] == 0) 
            {
                aux[i] = aux[i + 1] + 1;
                mark[arr[i]] = 1;
            }
            else
            {
                aux[i] = aux[i + 1];
            }
        }
      
        for (int i = 0; i < m; i++) 
        {
            Console.WriteLine(aux[q[i] - 1] );
        }
    }
      
    // Driver code
    static public void Main ()
    {
          
        int []arr = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
        int n = arr.Length;
        int []q = { 1, 3, 6 };
        int m = q.Length;
        printUniqueElementsInSuffix(arr, n, q, m);
    }
}
  
// This code is contributed by Sachin.


输出:
4
3
4

时间复杂度: O(N)
辅助空间:O(N)

不使用STL的方法:由于需要解决查询,因此需要进行预计算。否则,对后缀的简单遍历就足够了。

从数组的右侧维护辅助数组aux [] 。数组mark []存储元素是否已在后缀后缀中出现。如果没有发生该元素,则更新aux [i] = aux [i + 1] + 1 。否则aux [i] = aux [i + 1]

每个查询的答案都是aux [q [i]]

下面是上述方法的实现。

C++

// C++ implementation of the above approach.
#include 
  
#define MAX 100002
using namespace std;
  
// Function to print no of unique elements
// in specified suffix for each query.
void printUniqueElementsInSuffix(const int* arr,
                                 int n, const int* q, int m)
{
  
    // aux[i] stores no of unique elements in arr[i..n]
    int aux[MAX];
  
    // mark[i] = 1 if i has occurred in the suffix at least once.
    int mark[MAX];
    memset(mark, 0, sizeof(mark));
  
    // Initialization for the last element.
    aux[n - 1] = 1;
    mark[arr[n - 1]] = 1;
  
    for (int i = n - 2; i >= 0; i--) {
        if (mark[arr[i]] == 0) {
            aux[i] = aux[i + 1] + 1;
            mark[arr[i]] = 1;
        }
        else {
            aux[i] = aux[i + 1];
        }
    }
  
    for (int i = 0; i < m; i++) {
        cout << aux[q[i] - 1] << "\n";
    }
}
  
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int q[] = { 1, 3, 6 };
    int m = sizeof(q) / sizeof(q[0]);
    printUniqueElementsInSuffix(arr, n, q, m);
    return 0;
}

Java

// Java implementation of the above approach.
class GFG
{
      
static int MAX = 100002;
  
// Function to print no of unique elements
// in specified suffix for each query.
static void printUniqueElementsInSuffix(int[] arr,
                                int n, int[] q, int m)
{
  
    // aux[i] stores no of unique elements in arr[i..n]
    int []aux = new int[MAX];
  
    // mark[i] = 1 if i has occurred 
    // in the suffix at least once.
    int []mark = new int[MAX];
  
    // Initialization for the last element.
    aux[n - 1] = 1;
    mark[arr[n - 1]] = 1;
  
    for (int i = n - 2; i >= 0; i--) 
    {
        if (mark[arr[i]] == 0) 
        {
            aux[i] = aux[i + 1] + 1;
            mark[arr[i]] = 1;
        }
        else 
        {
            aux[i] = aux[i + 1];
        }
    }
  
    for (int i = 0; i < m; i++) 
    {
        System.out.println(aux[q[i] - 1] );
    }
}
  
// Driver code
public static void main(String[] args) 
{
  
    int arr[] = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
    int n = arr.length;
    int q[] = { 1, 3, 6 };
    int m = q.length;
    printUniqueElementsInSuffix(arr, n, q, m);
}
}
  
// This code is contributed by Princi Singh

Python3

# Python implementation of the above approach.
MAX = 100002;
  
# Function to prno of unique elements
# in specified suffix for each query.
def printUniqueElementsInSuffix(arr, n, q, m):
  
    # aux[i] stores no of unique elements in arr[i..n]
    aux = [0] * MAX;
  
    # mark[i] = 1 if i has occurred
    # in the suffix at least once.
    mark = [0] * MAX;
  
    # Initialization for the last element.
    aux[n - 1] = 1;
    mark[arr[n - 1]] = 1;
  
    for i in range(n - 2, -1, -1):
        if (mark[arr[i]] == 0):
            aux[i] = aux[i + 1] + 1;
            mark[arr[i]] = 1;
        else:
            aux[i] = aux[i + 1];
  
    for i in range(m):
        print(aux[q[i] - 1]);
  
# Driver code
if __name__ == '__main__':
    arr = [1, 2, 3, 4, 1, 2, 3, 4, 10000, 999];
    n = len(arr);
    q = [1, 3, 6];
    m = len(q);
    printUniqueElementsInSuffix(arr, n, q, m);
  
# This code is contributed by 29AjayKumar

C#

// C# implementation of the above approach.
using System;
  
class GFG
{
    static int MAX = 100002;
  
    // Function to print no of unique elements
    // in specified suffix for each query.
    static void printUniqueElementsInSuffix(int[] arr,
                                    int n, int[] q, int m)
    {
      
        // aux[i] stores no of unique elements in arr[i..n]
        int []aux = new int[MAX];
      
        // mark[i] = 1 if i has occurred 
        // in the suffix at least once.
        int []mark = new int[MAX];
      
        // Initialization for the last element.
        aux[n - 1] = 1;
        mark[arr[n - 1]] = 1;
      
        for (int i = n - 2; i >= 0; i--) 
        {
            if (mark[arr[i]] == 0) 
            {
                aux[i] = aux[i + 1] + 1;
                mark[arr[i]] = 1;
            }
            else
            {
                aux[i] = aux[i + 1];
            }
        }
      
        for (int i = 0; i < m; i++) 
        {
            Console.WriteLine(aux[q[i] - 1] );
        }
    }
      
    // Driver code
    static public void Main ()
    {
          
        int []arr = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
        int n = arr.Length;
        int []q = { 1, 3, 6 };
        int m = q.Length;
        printUniqueElementsInSuffix(arr, n, q, m);
    }
}
  
// This code is contributed by Sachin.
输出:
6
6
5