📌  相关文章
📜  给定数组中大于下 K 个元素的数字计数

📅  最后修改于: 2022-05-13 01:57:00.833000             🧑  作者: Mango

给定数组中大于下 K 个元素的数字计数

给定一个大小为N的整数数组arr[] ,任务是计算其值于其紧邻右侧的所有K个元素的元素的数量。如果第 i 个元素右侧的数字小于 K,则它们的值都必须小于第 i 个人的值。

例子:

朴素的方法:对于每个元素,检查 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)