Element which occurs consecutively in a given subarray more than or equal to K times

Given an array of size N and Q queries, each query consists of L, R, and K(consider 1 based-indexing for L and R). The task is to find an element for each query that occurs consecutively in the subarray [L, R] more than or equal to K times. K will always be greater than floor((R-L+1)/2). If no such element exists, print -1.

Examples:

Input: arr[] = [1, 3, 3, 3, 4]
Q = 1
L = 1, R = 5, K = 3
Output: 3
The element 3 occurs 3 times consecutively in the range [1, 5]

Input: arr[] = [3, 2, 1, 1, 2, 2, 2, 2]
Q = 2
L = 2, R = 6, K = 3
L = 3, R = 8, K = 4
Output:
-1
2

Approach: Create two auxiliary arrays left and right of size n. The Left array will store the count of elements from the start that occurs consecutively in the array. The Right array will store count of elements from back that occurs consecutively in the array. Since it is given in the question that k will always be greater than floor((R-L+1)/2). Hence if any such element exists in the given range, it is always lie in the index mid. Mathematically, min{ right[mid] + mid – 1, r – 1 }-max{ mid – left[mid] + 1, l – 1} + 1 will give the range of the element in the subarray L-R which lies at the index mid. If the range exceeds or is equal to k, then return the a[mid] element. If it is not then return -1.

Below is the implementation of above approach :

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 <bits/stdc++.h>
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);
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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] *
  
    # 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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..

chevron_right


Output:

-1
2

Time complexity: O(N) to pre-compute the left andd right array and O(1) to answer every query.
Auxiliary Space: O(N)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.