给定数组中大于下 K 个元素的数字计数
给定一个大小为N的整数数组arr[] ,任务是计算其值大于其紧邻右侧的所有K个元素的元素的数量。如果第 i 个元素右侧的数字小于 K,则它们的值都必须小于第 i 个人的值。
例子:
Input: arr[] = {4, 3, 1, 2, 5}, N = 5, K = 1
Output: 3
Explanation: The 1st ,2nd and 5th are the elements whose values are greater than the element to its right(As k = 1 consider only the next). While the 3rd element can not be considered because of the 4th element whose value is greater than the 3rd element’s value.
Input: arr[] = {9, 7, 7, 7, 4}, N = 5, K = 3
Output: 3
Explanation: The 1st ,4th and the 5th element will be the elements whose values are greater than all 3 elements elements after it.
朴素的方法:对于每个元素,检查 K 个元素到它们的右端,看看它是否大于所有这些元素。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效方法:可以使用以下步骤解决此问题:
- 考虑一个存储 K 个元素的队列。
- 将 K 个元素从最后一个添加到队列中,并将最后 K 个值的最大值保存在一个变量中(例如,max_value)。
- 从位置 (N – K) 向后迭代剩余的数组。
- 迭代时从队列中弹出一个元素并推送队列中的当前元素。
- 如果当前元素的值大于max_value,则增加计数并将 max_value更新为当前元素。
- 否则,如果弹出的值与 max_value相同,则从队列中找到新的最大值。
- 返回计数值作为其值大于其紧邻右侧的所有 k 个元素的元素的计数。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to find
// maximum element in queue
int find_max(queue q)
{
int ans = INT_MIN;
// Loop to find maximum from queue
while (!q.empty()) {
ans = max(ans, q.front());
q.pop();
}
return ans;
}
// Function to count the elements
// whose values are greater than
// all the k elements to its immediate right
int solve(int n, int k, vector arr)
{
int max_value = INT_MIN;
queue q;
int count = 0;
int p = n - k;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Traversing last k elements
for (int i = n - 1; i >= p; i--) {
q.push(arr[i]);
if (arr[i] > max_value) {
max_value = arr[i];
count++;
}
}
// Traversing rest of the elements
for (int i = p - 1; i >= 0; i--) {
int x = q.front();
q.pop();
q.push(arr[i]);
if (arr[i] > max_value) {
count++;
max_value = arr[i];
}
else {
if (x == max_value) {
// If popped value
// is same as max value
// then update max value
max_value = find_max(q);
}
}
}
return count;
}
// Driver Code Starts.
int main()
{
int N, K;
N = 5;
K = 1;
vector arr = { 4, 3, 1, 2, 5};
cout << solve(N, K, arr) << "\n";
return 0;
}
Java
// Java code to implement the above approach
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
class GFG {
// Function to find
// maximum element in queue
public static int find_max(Queue q) {
int ans = Integer.MIN_VALUE;
// Loop to find maximum from queue
while (!q.isEmpty()) {
ans = Math.max(ans, q.peek());
q.remove();
}
return ans;
}
// Function to count the elements
// whose values are greater than
// all the k elements to its immediate right
public static int solve(int n, int k, ArrayList arr) {
int max_value = Integer.MIN_VALUE;
Queue q = new LinkedList();
int count = 0;
int p = n - k;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Traversing last k elements
for (int i = n - 1; i >= p; i--) {
q.add(arr.get(i));
if (arr.get(i) > max_value) {
max_value = arr.get(i);
count++;
}
}
// Traversing rest of the elements
for (int i = p - 1; i >= 0; i--) {
int x = 0;
if (q.size() > 0) {
x = q.peek();
q.remove();
}
q.add(arr.get(i));
if (arr.get(i) > max_value) {
count++;
max_value = arr.get(i);
} else {
if (x == max_value) {
// If popped value
// is same as max value
// then update max value
max_value = find_max(q);
}
}
}
return count;
}
// Driver Code Starts.
public static void main(String args[]) {
int N, K;
N = 5;
K = 1;
ArrayList arr = new ArrayList<>();
arr.add(4);
arr.add(3);
arr.add(1);
arr.add(2);
arr.add(5);
System.out.println(solve(N, K, arr));
}
}
// This code is contributed by saurabh_jaiswal.
Python3
# Python3 code to implement the above approach
from queue import Queue
import copy
INT_MIN = -2147483648
# Function to find
# maximum element in queue
def find_max(q):
ans = INT_MIN
# Loop to find maximum from queue
while (not q.empty()):
ans = max(ans, q.get())
return ans
# Function to count the elements
# whose values are greater than
# all the k elements to its immediate right
def solve(n, k, arr):
max_value = INT_MIN
q = Queue()
count = 0
p = n - k
# Checking base cases
if (n == 0):
return 0
elif (k == 0):
return n
# Traversing last k elements
for i in range(n - 1, p - 1, -1):
q.put(arr[i])
if (arr[i] > max_value):
max_value = arr[i]
count += 1
# Traversing rest of the elements
for i in range(p - 1, -1, -1):
x = q.get()
q.put(arr[i])
if (arr[i] > max_value):
count += 1
max_value = arr[i]
else:
if (x == max_value):
# If popped value is same
# as max value then update
# max value
temp = Queue()
for i in q.queue:
temp.put(i)
max_value = find_max(temp)
return count
# Driver code
if __name__ == "__main__":
N = 5
K = 1
arr = [ 4, 3, 1, 2, 5 ]
print(solve(N, K, arr))
# This code is contributed by rakeshsahni
C#
// C# code to implement the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to find
// maximum element in queue
public static int find_max(Queue q) {
int ans = int.MinValue;
// Loop to find maximum from queue
while (q.Count != 0) {
ans = Math.Max(ans, q.Peek());
q.Dequeue();
}
return ans;
}
// Function to count the elements
// whose values are greater than
// all the k elements to its immediate right
public static int solve(int n, int k, List arr) {
int max_value = int.MinValue;
Queue q = new Queue();
int count = 0;
int p = n - k;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Traversing last k elements
for (int i = n - 1; i >= p; i--) {
q.Enqueue(arr[i]);
if (arr[i] > max_value) {
max_value = arr[i];
count++;
}
}
// Traversing rest of the elements
for (int i = p - 1; i >= 0; i--) {
int x = 0;
if (q.Count > 0) {
x = q.Peek();
q.Dequeue();
}
q.Enqueue(arr[i]);
if (arr[i] > max_value) {
count++;
max_value = arr[i];
} else {
if (x == max_value) {
// If popped value
// is same as max value
// then update max value
max_value = find_max(q);
}
}
}
return count;
}
// Driver Code Starts.
public static void Main(String []args) {
int N, K;
N = 5;
K = 1;
List arr = new List();
arr.Add(4);
arr.Add(3);
arr.Add(1);
arr.Add(2);
arr.Add(5);
Console.WriteLine(solve(N, K, arr));
}
}
// This code is contributed by shikhasingrajput
Javascript
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to count the elements
// whose values are greater than
// all k elements to its immediate right
int solve(int n, int k, vector arr)
{
int count = 1;
int left = n - 2, right = n - 1;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Loop to implement two-pointer approach
for (; left >= 0; left--) {
if (right - left > k) {
right--;
while (arr[left] > arr[right])
right--;
if (right == left)
count++;
}
else if (arr[left] > arr[right]) {
count++;
right = left;
}
}
return count;
}
// Driver Code Starts.
int main()
{
int N, K;
N = 5;
K = 1;
vector arr = { 4, 3, 1, 2, 5};
cout << solve(N, K, arr);
return 0;
}
Java
// Java code to implement the above approach
import java.io.*;
class GFG{
// Function to count the elements
// whose values are greater than
// all k elements to its immediate right
static int solve(int n, int k, int[] arr)
{
int count = 1;
int left = n - 2, right = n - 1;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Loop to implement two-pointer approach
for(; left >= 0; left--)
{
if (right - left > k)
{
right--;
while (arr[left] > arr[right])
right--;
if (right == left)
count++;
}
else if (arr[left] > arr[right])
{
count++;
right = left;
}
}
return count;
}
// Driver Code
public static void main(String[] args)
{
int N, K;
N = 5;
K = 1;
int[] arr = { 4, 3, 1, 2, 5 };
System.out.println(solve(N, K, arr));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python 3 code to implement the above approach
# Function to count the elements
# whose values are greater than
# all k elements to its immediate right
def solve(n, k, arr):
count = 1
left = n - 2
right = n - 1
# Checking base cases
if (n == 0):
return 0
elif (k == 0):
return n
# Loop to implement two-pointer approach
while left >= 0:
if (right - left > k):
right -= 1
while (arr[left] > arr[right]):
right -= 1
if (right == left):
count += 1
elif (arr[left] > arr[right]):
count += 1
right = left
left -= 1
return count
# Driver Code
if __name__ == "__main__":
N = 5
K = 1
arr = [4, 3, 1, 2, 5]
print(solve(N, K, arr))
# This code is contributed by ukasp.
C#
// C# code to implement the above approach
using System;
public class GFG
{
// Function to count the elements
// whose values are greater than
// all k elements to its immediate right
static int solve(int n, int k, int[] arr)
{
int count = 1;
int left = n - 2, right = n - 1;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Loop to implement two-pointer approach
for(; left >= 0; left--)
{
if (right - left > k)
{
right--;
while (arr[left] > arr[right])
right--;
if (right == left)
count++;
}
else if (arr[left] > arr[right])
{
count++;
right = left;
}
}
return count;
}
// Driver Code
public static void Main(String[] args)
{
int N, K;
N = 5;
K = 1;
int[] arr = { 4, 3, 1, 2, 5 };
Console.WriteLine(solve(N, K, arr));
}
}
// This code is contributed by 29AjayKumar
Javascript
3
时间复杂度: O(N)
辅助空间: O(K)
空间优化方法:可以使用两个指针方法以较小的空间解决问题。请按照以下步骤操作。
- 初始化指向数组末尾的两个指针(比如“左”和“右”)。
- 左指针指向 K 大小窗口的起始索引,右指针指向该窗口中的最大值。
- 如果左指针的值大于右指针的值,则将答案计数增加 1。(因为这意味着它大于其紧邻右侧的所有 K 个元素)
- 如果在任何时候窗口大小超过 K,则将右指针减一并调整它以指向当前窗口的最大值。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to count the elements
// whose values are greater than
// all k elements to its immediate right
int solve(int n, int k, vector arr)
{
int count = 1;
int left = n - 2, right = n - 1;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Loop to implement two-pointer approach
for (; left >= 0; left--) {
if (right - left > k) {
right--;
while (arr[left] > arr[right])
right--;
if (right == left)
count++;
}
else if (arr[left] > arr[right]) {
count++;
right = left;
}
}
return count;
}
// Driver Code Starts.
int main()
{
int N, K;
N = 5;
K = 1;
vector arr = { 4, 3, 1, 2, 5};
cout << solve(N, K, arr);
return 0;
}
Java
// Java code to implement the above approach
import java.io.*;
class GFG{
// Function to count the elements
// whose values are greater than
// all k elements to its immediate right
static int solve(int n, int k, int[] arr)
{
int count = 1;
int left = n - 2, right = n - 1;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Loop to implement two-pointer approach
for(; left >= 0; left--)
{
if (right - left > k)
{
right--;
while (arr[left] > arr[right])
right--;
if (right == left)
count++;
}
else if (arr[left] > arr[right])
{
count++;
right = left;
}
}
return count;
}
// Driver Code
public static void main(String[] args)
{
int N, K;
N = 5;
K = 1;
int[] arr = { 4, 3, 1, 2, 5 };
System.out.println(solve(N, K, arr));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python 3 code to implement the above approach
# Function to count the elements
# whose values are greater than
# all k elements to its immediate right
def solve(n, k, arr):
count = 1
left = n - 2
right = n - 1
# Checking base cases
if (n == 0):
return 0
elif (k == 0):
return n
# Loop to implement two-pointer approach
while left >= 0:
if (right - left > k):
right -= 1
while (arr[left] > arr[right]):
right -= 1
if (right == left):
count += 1
elif (arr[left] > arr[right]):
count += 1
right = left
left -= 1
return count
# Driver Code
if __name__ == "__main__":
N = 5
K = 1
arr = [4, 3, 1, 2, 5]
print(solve(N, K, arr))
# This code is contributed by ukasp.
C#
// C# code to implement the above approach
using System;
public class GFG
{
// Function to count the elements
// whose values are greater than
// all k elements to its immediate right
static int solve(int n, int k, int[] arr)
{
int count = 1;
int left = n - 2, right = n - 1;
// Checking base cases
if (n == 0)
return 0;
else if (k == 0)
return n;
// Loop to implement two-pointer approach
for(; left >= 0; left--)
{
if (right - left > k)
{
right--;
while (arr[left] > arr[right])
right--;
if (right == left)
count++;
}
else if (arr[left] > arr[right])
{
count++;
right = left;
}
}
return count;
}
// Driver Code
public static void Main(String[] args)
{
int N, K;
N = 5;
K = 1;
int[] arr = { 4, 3, 1, 2, 5 };
Console.WriteLine(solve(N, K, arr));
}
}
// This code is contributed by 29AjayKumar
Javascript
3
时间复杂度: O(N)
辅助空间: O(1)