给定大小为N和Q的查询数组,每个查询由L,R和K组成(考虑L和R的基于1的索引)。任务是为每个查询找到一个在子数组[L,R]中连续发生超过或等于K次的元素。 K将始终大于floor((R-L + 1)/ 2) 。如果不存在这样的元素,则打印-1。
例子:
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
做法:创建两个辅助阵列左右的大小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现场课程美国》。