📌  相关文章
📜  Array元素的数量大于其左侧的所有元素,并且至少其右侧的K个元素

📅  最后修改于: 2021-04-17 10:11:15             🧑  作者: Mango

给定一个由N个不同的整数组成的数组A [] ,任务是查找元素数量,该数量严格大于其前面的所有元素,并且至少大于其右边的至少K个元素。

例子:

天真的方法:
解决问题的最简单方法是遍历数组,并针对每个元素遍历其左侧的所有元素,并检查所有元素是否小于它,然后遍历其右侧的所有元素,以检查是否至少有K个元素小于或小于。对于满足条件的每个元素,增加count 。最后,打印count的值。

时间复杂度: O(N 2 )
辅助空间: O(1)

高效方法:
通过使用自平衡BST,可以进一步优化上述方法。请按照以下步骤操作:

  • 从右到左遍历数组并将所有元素一一插入到AVL树中
  • 使用AVL树生成一个数组countSmaller [] ,该数组在每个数组元素的右侧包含较小元素的计数。
  • 遍历数组,并对于每个i元素,检查它是否是到目前为止获得的最大值,并且countSmaller [i]大于或等于K。
  • 如果是这样,请增加count
  • 打印count的最终值作为答案。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above appraoch
#include 
using namespace std;
 
// Structure of an AVL Tree Node
struct node {
    int key;
    struct node* left;
    struct node* right;
    int height;
    // Size of the tree rooted
    // with this node
    int size;
};
 
// Utility function to get maximum
// of two integers
int max(int a, int b);
 
// Utility function to get height
// of the tree rooted with N
int height(struct node* N)
{
    if (N == NULL)
        return 0;
    return N->height;
}
 
// Utility function to find size of
// the tree rooted with N
int size(struct node* N)
{
    if (N == NULL)
        return 0;
    return N->size;
}
 
// Utility function to get maximum
// of two integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Helper function to allocates a
// new node with the given key
struct node* newNode(int key)
{
    struct node* node
        = (struct node*)
            malloc(sizeof(struct node));
    node->key = key;
    node->left = NULL;
    node->right = NULL;
    node->height = 1;
    node->size = 1;
    return (node);
}
 
// Utility function to right rotate
// subtree rooted with y
struct node* rightRotate(struct node* y)
{
    struct node* x = y->left;
    struct node* T2 = x->right;
 
    // Perform rotation
    x->right = y;
    y->left = T2;
 
    // Update heights
    y->height = max(height(y->left),
                    height(y->right))
                + 1;
    x->height = max(height(x->left),
                    height(x->right))
                + 1;
 
    // Update sizes
    y->size = size(y->left)
              + size(y->right) + 1;
    x->size = size(x->left)
              + size(x->right) + 1;
 
    // Return new root
    return x;
}
 
// Utility function to left rotate
// subtree rooted with x
struct node* leftRotate(struct node* x)
{
    struct node* y = x->right;
    struct node* T2 = y->left;
 
    // Perform rotation
    y->left = x;
    x->right = T2;
 
    // Update heights
    x->height = max(height(x->left),
                    height(x->right))
                + 1;
    y->height = max(height(y->left),
                    height(y->right))
                + 1;
 
    // Update sizes
    x->size = size(x->left)
              + size(x->right) + 1;
    y->size = size(y->left)
              + size(y->right) + 1;
 
    // Return new root
    return y;
}
 
// Function to obtain Balance factor
// of node N
int getBalance(struct node* N)
{
    if (N == NULL)
        return 0;
 
    return height(N->left)
           - height(N->right);
}
 
// Function to insert a new key to the
// tree rooted with node
struct node* insert(struct node* node, int key,
                    int* count)
{
    // Perform the normal BST rotation
    if (node == NULL)
        return (newNode(key));
 
    if (key < node->key)
        node->left
            = insert(node->left, key, count);
    else {
        node->right
            = insert(node->right, key, count);
 
        // Update count of smaller elements
        *count = *count + size(node->left) + 1;
    }
 
    // Update height and size of the ancestor
    node->height = max(height(node->left),
                       height(node->right))
                   + 1;
    node->size = size(node->left)
                 + size(node->right) + 1;
 
    // Get the balance factor of the ancestor
    int balance = getBalance(node);
 
    // Left Left Case
    if (balance > 1 && key < node->left->key)
        return rightRotate(node);
 
    // Right Right Case
    if (balance < -1 && key > node->right->key)
        return leftRotate(node);
 
    // Left Right Case
    if (balance > 1 && key > node->left->key) {
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }
 
    // Right Left Case
    if (balance < -1 && key < node->right->key) {
        node->right = rightRotate(node->right);
        return leftRotate(node);
    }
 
    return node;
}
 
// Function to generate an array which contains
// count of smaller elements on the right
void constructLowerArray(int arr[],
                         int countSmaller[],
                         int n)
{
    int i, j;
    struct node* root = NULL;
 
    for (i = 0; i < n; i++)
        countSmaller[i] = 0;
 
    // Insert all elements in the AVL Tree
    // and get the count of smaller elements
    for (i = n - 1; i >= 0; i--) {
        root = insert(root, arr[i],
                      &countSmaller[i]);
    }
}
 
// Function to find the number
// of elements which are greater
// than all elements on its left
// and K elements on its right
int countElements(int A[], int n, int K)
{
 
    int count = 0;
 
    // Stores the count of smaller
    // elements on its right
    int* countSmaller
        = (int*)malloc(sizeof(int) * n);
    constructLowerArray(A, countSmaller, n);
 
    int maxi = INT_MIN;
    for (int i = 0; i <= (n - K - 1); i++) {
        if (A[i] > maxi && countSmaller[i] >= K) {
            count++;
            maxi = A[i];
        }
    }
 
    return count;
}
 
// Driver Code
int main()
{
 
    int A[] = { 2, 5, 1, 7, 3, 4, 0 };
    int n = sizeof(A) / sizeof(int);
    int K = 3;
 
    cout << countElements(A, n, K);
 
    return 0;
}


Java
// Java program to implement
// the above appraoch
class GFG{
 
// Structure of an AVL Tree Node
static class Node
{
    int key;
    Node left;
    Node right;
    int height;
     
    // Size of the tree rooted
    // with this Node
    int size;
 
    public Node(int key)
    {
        this.key = key;
        this.left = this.right = null;
        this.size = this.height = 1;
    }
};
 
// Helper class to pass Integer
// as referencee
static class RefInteger
{
    Integer value;
     
    public RefInteger(Integer value)
    {
        this.value = value;
    }
}
 
// Utility function to get height
// of the tree rooted with N
static int height(Node N)
{
    if (N == null)
        return 0;
         
    return N.height;
}
 
// Utility function to find size of
// the tree rooted with N
static int size(Node N)
{
    if (N == null)
        return 0;
         
    return N.size;
}
 
// Utility function to get maximum
// of two integers
static int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Utility function to right rotate
// subtree rooted with y
static Node rightRotate(Node y)
{
    Node x = y.left;
    Node T2 = x.right;
 
    // Perform rotation
    x.right = y;
    y.left = T2;
 
    // Update heights
    y.height = max(height(y.left),
                   height(y.right)) + 1;
    x.height = max(height(x.left),
                   height(x.right)) + 1;
   
    // Update sizes
    y.size = size(y.left) +
             size(y.right) + 1;
    x.size = size(x.left) +
             size(x.right) + 1;
 
    // Return new root
    return x;
}
 
// Utility function to left rotate
// subtree rooted with x
static Node leftRotate(Node x)
{
    Node y = x.right;
    Node T2 = y.left;
 
    // Perform rotation
    y.left = x;
    x.right = T2;
 
    // Update heights
    x.height = max(height(x.left),
                   height(x.right)) + 1;
    y.height = max(height(y.left),
                   height(y.right)) + 1;
   
    // Update sizes
    x.size = size(x.left) +
             size(x.right) + 1;
    y.size = size(y.left) +
             size(y.right) + 1;
 
    // Return new root
    return y;
}
 
// Function to obtain Balance factor
// of Node N
static int getBalance(Node N)
{
    if (N == null)
        return 0;
 
    return height(N.left) -
           height(N.right);
}
 
// Function to insert a new key to the
// tree rooted with Node
static Node insert(Node Node, int key,
                   RefInteger count)
{
     
    // Perform the normal BST rotation
    if (Node == null)
        return (new Node(key));
 
    if (key < Node.key)
        Node.left = insert(Node.left,
                           key, count);
    else
    {
        Node.right = insert(Node.right,
                            key, count);
 
        // Update count of smaller elements
        count.value = count.value +
                  size(Node.left) + 1;
    }
 
    // Update height and size of the ancestor
    Node.height = max(height(Node.left),
                      height(Node.right)) + 1;
    Node.size = size(Node.left) +
                size(Node.right) + 1;
 
    // Get the balance factor of the ancestor
    int balance = getBalance(Node);
 
    // Left Left Case
    if (balance > 1 && key < Node.left.key)
        return rightRotate(Node);
 
    // Right Right Case
    if (balance < -1 && key > Node.right.key)
        return leftRotate(Node);
 
    // Left Right Case
    if (balance > 1 && key > Node.left.key)
    {
        Node.left = leftRotate(Node.left);
        return rightRotate(Node);
    }
 
    // Right Left Case
    if (balance < -1 && key < Node.right.key)
    {
        Node.right = rightRotate(Node.right);
        return leftRotate(Node);
    }
    return Node;
}
 
// Function to generate an array which
// contains count of smaller elements
// on the right
static void constructLowerArray(int arr[],
     RefInteger[] countSmaller, int n)
{
    int i, j;
    Node root = null;
 
    for(i = 0; i < n; i++)
        countSmaller[i] = new RefInteger(0);
 
    // Insert all elements in the AVL Tree
    // and get the count of smaller elements
    for(i = n - 1; i >= 0; i--)
    {
        root = insert(root, arr[i],
                   countSmaller[i]);
    }
}
 
// Function to find the number
// of elements which are greater
// than all elements on its left
// and K elements on its right
static int countElements(int A[], int n,
                         int K)
{
    int count = 0;
 
    // Stores the count of smaller
    // elements on its right
    RefInteger[] countSmaller = new RefInteger[n];
    constructLowerArray(A, countSmaller, n);
 
    int maxi = Integer.MIN_VALUE;
    for(int i = 0; i <= (n - K - 1); i++)
    {
        if (A[i] > maxi &&
            countSmaller[i].value >= K)
        {
            count++;
            maxi = A[i];
        }
    }
    return count;
}
 
// Driver Code
public static void main(String[] args)
{
    int A[] = { 2, 5, 1, 7, 3, 4, 0 };
    int n = A.length;
    int K = 3;
 
    System.out.println(countElements(A, n, K));
}
}
 
// This code is contributed by sanjeev2552


C#
// C# program to implement
// the above appraoch
using System;
using System.Collections.Generic;
 
class GFG{
 
// Structure of an AVL Tree Node
public class Node
{
    public int key;
    public Node left;
    public Node right;
    public int height;
     
    // Size of the tree rooted
    // with this Node
    public int size;
 
    public Node(int key)
    {
        this.key = key;
        this.left = this.right = null;
        this.size = this.height = 1;
    }
};
 
// Helper class to pass int
// as referencee
public class Refint
{
    public int value;
     
    public Refint(int value)
    {
        this.value = value;
    }
}
 
// Utility function to get height
// of the tree rooted with N
static int height(Node N)
{
    if (N == null)
        return 0;
         
    return N.height;
}
 
// Utility function to find size of
// the tree rooted with N
static int size(Node N)
{
    if (N == null)
        return 0;
         
    return N.size;
}
 
// Utility function to get maximum
// of two integers
static int max(int a, int b)
{
    return (a > b) ? a : b;
}
 
// Utility function to right rotate
// subtree rooted with y
static Node rightRotate(Node y)
{
    Node x = y.left;
    Node T2 = x.right;
 
    // Perform rotation
    x.right = y;
    y.left = T2;
 
    // Update heights
    y.height = max(height(y.left),
                   height(y.right)) + 1;
    x.height = max(height(x.left),
                   height(x.right)) + 1;
   
    // Update sizes
    y.size = size(y.left) +
             size(y.right) + 1;
    x.size = size(x.left) +
             size(x.right) + 1;
 
    // Return new root
    return x;
}
 
// Utility function to left rotate
// subtree rooted with x
static Node leftRotate(Node x)
{
    Node y = x.right;
    Node T2 = y.left;
 
    // Perform rotation
    y.left = x;
    x.right = T2;
 
    // Update heights
    x.height = max(height(x.left),
                   height(x.right)) + 1;
    y.height = max(height(y.left),
                   height(y.right)) + 1;
   
    // Update sizes
    x.size = size(x.left) +
             size(x.right) + 1;
    y.size = size(y.left) +
             size(y.right) + 1;
 
    // Return new root
    return y;
}
 
// Function to obtain Balance factor
// of Node N
static int getBalance(Node N)
{
    if (N == null)
        return 0;
 
    return height(N.left) -
           height(N.right);
}
 
// Function to insert a new key to the
// tree rooted with Node
static Node insert(Node Node, int key,
                   Refint count)
{
     
    // Perform the normal BST rotation
    if (Node == null)
        return (new Node(key));
 
    if (key < Node.key)
        Node.left = insert(Node.left,
                           key, count);
    else
    {
        Node.right = insert(Node.right,
                            key, count);
 
        // Update count of smaller elements
        count.value = count.value +
                  size(Node.left) + 1;
    }
 
    // Update height and size of the ancestor
    Node.height = max(height(Node.left),
                      height(Node.right)) + 1;
    Node.size = size(Node.left) +
                size(Node.right) + 1;
 
    // Get the balance factor of the ancestor
    int balance = getBalance(Node);
 
    // Left Left Case
    if (balance > 1 && key < Node.left.key)
        return rightRotate(Node);
 
    // Right Right Case
    if (balance < -1 && key > Node.right.key)
        return leftRotate(Node);
 
    // Left Right Case
    if (balance > 1 && key > Node.left.key)
    {
        Node.left = leftRotate(Node.left);
        return rightRotate(Node);
    }
 
    // Right Left Case
    if (balance < -1 && key < Node.right.key)
    {
        Node.right = rightRotate(Node.right);
        return leftRotate(Node);
    }
    return Node;
}
 
// Function to generate an array which
// contains count of smaller elements
// on the right
static void constructLowerArray(int []arr,
         Refint[] countSmaller, int n)
{
    int i;
    //int j;
    Node root = null;
 
    for(i = 0; i < n; i++)
        countSmaller[i] = new Refint(0);
 
    // Insert all elements in the AVL Tree
    // and get the count of smaller elements
    for(i = n - 1; i >= 0; i--)
    {
        root = insert(root, arr[i],
                   countSmaller[i]);
    }
}
 
// Function to find the number
// of elements which are greater
// than all elements on its left
// and K elements on its right
static int countElements(int []A, int n,
                         int K)
{
    int count = 0;
 
    // Stores the count of smaller
    // elements on its right
    Refint[] countSmaller = new Refint[n];
    constructLowerArray(A, countSmaller, n);
 
    int maxi = int.MinValue;
    for(int i = 0; i <= (n - K - 1); i++)
    {
        if (A[i] > maxi &&
            countSmaller[i].value >= K)
        {
            count++;
            maxi = A[i];
        }
    }
    return count;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []A = { 2, 5, 1, 7, 3, 4, 0 };
    int n = A.Length;
    int K = 3;
 
    Console.WriteLine(countElements(A, n, K));
}
}
 
// This code is contributed by Princi Singh


输出:
2

时间复杂度: O(NlogN)
辅助空间: O(N)