📌  相关文章
📜  在给定子数组中连续出现超过或等于K次的元素

📅  最后修改于: 2021-06-26 12:45:17             🧑  作者: Mango

给定大小为N和Q的查询数组,每个查询由L,R和K组成(考虑L和R的基于1的索引)。任务是为每个查询找到一个在子数组[L,R]中连续发生超过或等于K次的元素。 K将始终大于floor((R-L + 1)/ 2) 。如果不存在这样的元素,则打印-1。
例子:

做法:创建两个辅助阵列左右的大小n。 Left数组将从头开始存储在数组中连续发生的元素数。 Right数组将存储数组中连续出现的从后方开始的元素计数。由于给出的问题是k总是大于floor((R-L + 1)/ 2) 。因此,如果在给定范围内存在任何此类元素,则该元素始终位于索引mid内。数学上, min {右[mid] +中间– 1,r – 1} -max {中间–左[mid] + 1,l – 1} + 1将给出子数组LR中元素的范围,该子数组位于索引中。如果范围超过或等于k,则返回a [mid]元素。如果不是,则返回-1。
下面是上述方法的实现:

C++
// CPP program to find the element for each
// query that occurs consecutively in the
// subarray [L, R] more than or equal to K times.
#include 
using namespace std;
 
/// Function to find the element for each
/// query that occurs consecutively in the
/// subarray [L, R] more than or equal to K times.
int findElement(int arr[], int left[], int right[],
                int n, int l, int r, int k)
{
    // find mid point of subarray [L, R]
    int mid = (l - 1 + r - 1) / 2;
 
    // find starting and ending index of range
    int s = max(mid - left[mid] + 1, l - 1);
    int e = min(right[mid] + mid - 1, r - 1);
 
    int range = e - s + 1;
 
    // compare this range with k
    // if it is greater than or
    // equal to k, return element
    if (range >= k)
        return arr[mid];
    // if not then return -1
    else
        return -1;
}
 
// function to answer query in range [L, R]
int answerQuery(int arr[], int n, int l, int r, int k)
{
    int left[n], right[n];
 
    // store count of elements that occur
    // consecutively in the array [1, n]
    int count = 1;
    for (int i = 0; i < n - 1; i++) {
        if (arr[i] == arr[i + 1]) {
            left[i] = count;
            count++;
        }
        else {
            left[i] = count;
            count = 1;
        }
    }
    left[n - 1] = count;
 
    // store count of elements that occur
    // consecutively in the array [n, 1]
    count = 1;
    for (int i = n - 1; i > 0; i--) {
        if (arr[i] == arr[i - 1]) {
            right[i] = count;
            count++;
        }
        else {
            right[i] = count;
            count = 1;
        }
    }
    right[0] = count;
 
    // Function to return the element
    return findElement(arr, left, right, n, l, r, k);
}
 
// Driver Code
int main()
{
    int a[] = { 3, 2, 1, 1, 2, 2, 2, 2 };
    int n = sizeof(a) / sizeof(a[0]);
 
    // 1st query
    int L = 2, R = 6, k = 3;
    cout << answerQuery(a, n, L, R, k) << "\n";
 
    // 2nd query
    L = 3, R = 8, k = 4;
    cout << answerQuery(a, n, L, R, k);
}


Java
// Java program to find the element for each
// query that occurs consecutively in the
// subarray [L, R] more than or equal to K times.
import java.util.*;
 
class solution
{
 
/// Function to find the element for each
/// query that occurs consecutively in the
/// subarray [L, R] more than or equal to K times.
static int findElement(int[] arr, int[] left, int[] right,
                int n, int l, int r, int k)
{
    // find mid point of subarray [L, R]
    int mid = (l - 1 + r - 1) / 2;
 
    // find starting and ending index of range
    int s = Math.max(mid - left[mid] + 1, l - 1);
    int e = Math.min(right[mid] + mid - 1, r - 1);
 
    int range = e - s + 1;
 
    // compare this range with k
    // if it is greater than or
    // equal to k, return element
    if (range >= k)
        return arr[mid];
    // if not then return -1
    else
        return -1;
}
 
// function to answer query in range [L, R]
static int answerQuery(int arr[], int n, int l, int r, int k)
{
    int[] left = new int[n];
    int[] right = new int[n];
 
    // store count of elements that occur
    // consecutively in the array [1, n]
    int count = 1;
    for (int i = 0; i < n - 1; i++) {
        if (arr[i] == arr[i + 1]) {
            left[i] = count;
            count++;
        }
        else {
            left[i] = count;
            count = 1;
        }
    }
    left[n - 1] = count;
 
    // store count of elements that occur
    // consecutively in the array [n, 1]
    count = 1;
    for (int i = n - 1; i > 0; i--) {
        if (arr[i] == arr[i - 1]) {
            right[i] = count;
            count++;
        }
        else {
            right[i] = count;
            count = 1;
        }
    }
    right[0] = count;
 
    // Function to return the element
    return findElement(arr, left, right, n, l, r, k);
}
 
// Driver Code
public static void main(String args[])
{
    int[] a = { 3, 2, 1, 1, 2, 2, 2, 2 };
    int n = a.length;
 
    // 1st query
    int L = 2, R = 6, k = 3;
    System.out.println(answerQuery(a, n, L, R, k));
 
    // 2nd query
    L = 3;
    R = 8;
    k = 4;
    System.out.println(answerQuery(a, n, L, R, k));
}
 
}
// This code is contributed by
// Shashank_Sharma


Python3
# Python3 program to find the element for each
# query that occurs consecutively in the
# subarray [L, R] more than or equal to K times.
 
# Function to find the element for each
# query that occurs consecutively in the
# subarray [L, R] more than or equal to K times.
def findElement(arr, left, right, n, l, r, k):
  
    # find mid point of subarray [L, R]
    mid = (l - 1 + r - 1) // 2
 
    # find starting and ending index of range
    s = max(mid - left[mid] + 1, l - 1)
    e = min(right[mid] + mid - 1, r - 1)
 
    _range = e - s + 1
 
    # compare this range with k
    # if it is greater than or
    # equal to k, return element
    if _range >= k:
        return arr[mid]
    # if not then return -1
    else:
        return -1
 
# function to answer query in range [L, R]
def answerQuery(arr, n, l, r, k):
  
    left, right = [None] * n, [None] * n
 
    # store count of elements that occur
    # consecutively in the array [1, n]
    count = 1
    for i in range(0, n - 1): 
        if arr[i] == arr[i + 1]: 
            left[i] = count
            count += 1
          
        else:
            left[i] = count
            count = 1
          
    left[n - 1] = count
 
    # store count of elements that occur
    # consecutively in the array [n, 1]
    count = 1
    for i in range(n - 1, 0, -1): 
        if arr[i] == arr[i - 1]: 
            right[i] = count
            count += 1
          
        else:
            right[i] = count
            count = 1
          
    right[0] = count
 
    # Function to return the element
    return findElement(arr, left, right, n, l, r, k)
  
# Driver Code
if __name__ == "__main__":
  
    a = [3, 2, 1, 1, 2, 2, 2, 2] 
    n = len(a)
 
    # 1st query
    L, R, k = 2, 6, 3
    print(answerQuery(a, n, L, R, k))
 
    # 2nd query
    L, R, k = 3, 8, 4
    print(answerQuery(a, n, L, R, k))
  
# This code is contributed by Rituraj Jain


C#
// C# program to find the element for each
// query that occurs consecutively in the
// subarray [L, R] more than or equal to K times.
using System;
 
class GFG
{
     
// Function to find the element for each
// query that occurs consecutively in the
// subarray [L, R] more than or equal to K times.
static int findElement(int[] arr, int[] left, int[] right,
                int n, int l, int r, int k)
{
    // find mid point of subarray [L, R]
    int mid = (l - 1 + r - 1) / 2;
 
    // find starting and ending index of range
    int s = Math.Max(mid - left[mid] + 1, l - 1);
    int e = Math.Min(right[mid] + mid - 1, r - 1);
 
    int range = e - s + 1;
 
    // compare this range with k
    // if it is greater than or
    // equal to k, return element
    if (range >= k)
        return arr[mid];
         
    // if not then return -1
    else
        return -1;
}
 
// function to answer query in range [L, R]
static int answerQuery(int []arr, int n,
                        int l, int r, int k)
{
    int[] left = new int[n];
    int[] right = new int[n];
 
    // store count of elements that occur
    // consecutively in the array [1, n]
    int count = 1;
    for (int i = 0; i < n - 1; i++)
    {
        if (arr[i] == arr[i + 1])
        {
            left[i] = count;
            count++;
        }
        else
        {
            left[i] = count;
            count = 1;
        }
    }
    left[n - 1] = count;
 
    // store count of elements that occur
    // consecutively in the array [n, 1]
    count = 1;
    for (int i = n - 1; i > 0; i--)
    {
        if (arr[i] == arr[i - 1])
        {
            right[i] = count;
            count++;
        }
        else
        {
            right[i] = count;
            count = 1;
        }
    }
    right[0] = count;
 
    // Function to return the element
    return findElement(arr, left, right, n, l, r, k);
}
 
// Driver Code
static public void Main ()
{
     
    int[] a = { 3, 2, 1, 1, 2, 2, 2, 2 };
    int n = a.Length;
     
    // 1st query
    int L = 2, R = 6, k = 3;
    Console.WriteLine(answerQuery(a, n, L, R, k));
 
    // 2nd query
    L = 3;
    R = 8;
    k = 4;
    Console.WriteLine(answerQuery(a, n, L, R, k));
}
}
 
// This code is contributed by ajit..


Javascript


输出:
-1
2

时间复杂度: O(N)可以预先计算左右数组,O(1)可以回答每个查询。
辅助空间: O(N)

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。