Given a stream of integers, lookup the rank of a given integer x. Rank of an integer in-stream is “Total number of elements less than or equal to x (not including x)”.
If an element is not found in the stream or is smallest in stream, return -1.
Examples:
Input : arr[] = {10, 20, 15, 3, 4, 4, 1}
x = 4;
Output : Rank of 4 in stream is: 3
There are total three elements less than
or equal to x (and not including x)
Input : arr[] = {5, 1, 14, 4, 15, 9, 7, 20, 11},
x = 20;
Output : Rank of 20 in stream is: 8
A relatively easy way to implement this is to use an array that holds all the elements in sorted order. When a new element is inserted we would shift the elements. Then we perform binary search on the array to get the right-most index of x and return that index. getRank(x) would work in O(log n) but insertion would be costly.
An efficient way is to use a Binary Search Tree. Each Node will hold the data value and size of its left subtree.
We traverse the tree from root and compare the root values to x.
- If root->data == x, return size of left subtree of root.
- If x < root->data, return getRank(root->left)
- If x > root->data, return getRank(root->right) + size of leftSubtree + 1.
Below is the solution.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
int leftSize;
};
Node* newNode(int data)
{
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
temp->leftSize = 0;
return temp;
}
Node* insert(Node*& root, int data)
{
if (!root)
return newNode(data);
if (data <= root->data) {
root->left = insert(root->left, data);
root->leftSize++;
}
else
root->right = insert(root->right, data);
return root;
}
int getRank(Node* root, int x)
{
if (root->data == x)
return root->leftSize;
if (x < root->data) {
if (!root->left)
return -1;
else
return getRank(root->left, x);
}
else {
if (!root->right)
return -1;
else {
int rightSize = getRank(root->right, x);
if(rightSize == -1 ) return -1;
return root->leftSize + 1 + rightSize;
}
}
}
int main()
{
int arr[] = { 5, 1, 4, 4, 5, 9, 7, 13, 3 };
int n = sizeof(arr) / sizeof(arr[0]);
int x = 4;
Node* root = NULL;
for (int i = 0; i < n; i++)
root = insert(root, arr[i]);
cout << "Rank of " << x << " in stream is: "
<< getRank(root, x) << endl;
x = 13;
cout << "Rank of " << x << " in stream is: "
<< getRank(root, x) << endl;
x = 8;
cout << "Rank of " << x << " in stream is: "
<< getRank(root, x) << endl;
return 0;
}
|
Java
class GfG {
static class Node {
int data;
Node left, right;
int leftSize;
}
static Node newNode(int data)
{
Node temp = new Node();
temp.data = data;
temp.left = null;
temp.right = null;
temp.leftSize = 0;
return temp;
}
static Node insert(Node root, int data)
{
if (root == null)
return newNode(data);
if (data <= root.data) {
root.left = insert(root.left, data);
root.leftSize++;
}
else
root.right = insert(root.right, data);
return root;
}
static int getRank(Node root, int x)
{
if (root.data == x)
return root.leftSize;
if (x < root.data) {
if (root.left == null)
return -1;
else
return getRank(root.left, x);
}
else {
if (root.right == null)
return -1;
else {
int rightSize = getRank(root.right, x);
if(rightSize == -1) return -1;
return root.leftSize + 1 + rightSize;
}
}
}
public static void main(String[] args)
{
int arr[] = { 5, 1, 4, 4, 5, 9, 7, 13, 3 };
int n = arr.length;
int x = 4;
Node root = null;
for (int i = 0; i < n; i++)
root = insert(root, arr[i]);
System.out.println("Rank of " + x + " in stream is : "+getRank(root, x));
x = 13;
System.out.println("Rank of " + x + " in stream is : "+getRank(root, x));
}
}
|
Python3
class newNode:
def __init__(self, data):
self.data = data
self.left = self.right = None
self.leftSize = 0
def insert(root, data):
if root is None:
return newNode(data)
if data <= root.data:
root.left = insert(root.left, data)
root.leftSize += 1
else:
root.right = insert(root.right, data)
return root
def getRank(root, x):
if root.data == x:
return root.leftSize
if x < root.data:
if root.left is None:
return -1
else:
return getRank(root.left, x)
else:
if root.right is None:
return -1
else:
rightSize = getRank(root.right, x)
if rightSize == -1:
return -1
else:
return root.leftSize + 1 + rightSize
if __name__ == '__main__':
arr = [5, 1, 4, 4, 5, 9, 7, 13, 3]
n = len(arr)
x = 4
root = None
for i in range(n):
root = insert(root, arr[i])
print("Rank of", x, "in stream is:",
getRank(root, x))
x = 13
print("Rank of", x, "in stream is:",
getRank(root, x))
x = 8
print("Rank of", x, "in stream is:",
getRank(root, x))
|
C#
using System;
class GFG
{
public class Node
{
public int data;
public Node left, right;
public int leftSize;
}
static Node newNode(int data)
{
Node temp = new Node();
temp.data = data;
temp.left = null;
temp.right = null;
temp.leftSize = 0;
return temp;
}
static Node insert(Node root, int data)
{
if (root == null)
return newNode(data);
if (data <= root.data)
{
root.left = insert(root.left, data);
root.leftSize++;
}
else
root.right = insert(root.right, data);
return root;
}
static int getRank(Node root, int x)
{
if (root.data == x)
return root.leftSize;
if (x < root.data)
{
if (root.left == null)
return -1;
else
return getRank(root.left, x);
}
else
{
if (root.right == null)
return -1;
else
{
int rightSize = getRank(root.right, x);
if(rightSize == -1) return -1;
return root.leftSize + 1 + rightSize;
}
}
}
public static void Main(String[] args)
{
int []arr = { 5, 1, 4, 4, 5, 9, 7, 13, 3 };
int n = arr.Length;
int x = 4;
Node root = null;
for (int i = 0; i < n; i++)
root = insert(root, arr[i]);
Console.WriteLine("Rank of " + x +
" in stream is : " +
getRank(root, x));
x = 13;
Console.WriteLine("Rank of " + x +
" in stream is : " +
getRank(root, x));
}
}
|
Output
Rank of 4 in stream is: 3
Rank of 13 in stream is: 8
Rank of 8 in stream is: -1
Another approach:
Traverse the array from the beginning. While traversing, count the nodes which is equal to or less than the given key.Print the count(Rank).
C++
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a[] = {5, 1, 14, 4, 15, 9, 7, 20, 11};
int key = 20;
int arraySize = sizeof(a)/sizeof(a[0]);
int count = 0;
for(int i = 0; i < arraySize; i++)
{
if(a[i] <= key)
{
count += 1;
}
}
cout << "Rank of " << key << " in stream is: "
<< count-1 << endl;
return 0;
}
|
Java
class GFG
{
public static void main(String[] args)
{
int a[] = {5, 1, 14, 4, 15, 9, 7, 20, 11};
int key = 20;
int arraySize = a.length;
int count = 0;
for(int i = 0; i < arraySize; i++)
{
if(a[i] <= key)
{
count += 1;
}
}
System.out.println("Rank of " + key +
" in stream is: " + (count - 1));
}
}
|
Python3
if __name__ == '__main__':
a = [5, 1, 14, 4, 15,
9, 7, 20, 11]
key = 20
arraySize = len(a)
count = 0
for i in range(arraySize):
if a[i] <= key:
count += 1
print("Rank of", key,
"in stream is:", count - 1)
|
C#
using System;
class GFG
{
public static void Main()
{
int []a = {5, 1, 14, 4, 15, 9, 7, 20, 11};
int key = 20;
int arraySize = a.Length;
int count = 0;
for(int i = 0; i < arraySize; i++)
{
if(a[i] <= key)
{
count += 1;
}
}
Console.WriteLine("Rank of " + key +
" in stream is: " +
(count - 1));
}
}
|
PHP
<?php
$a = array(5, 1, 14, 4, 15, 9, 7, 20, 11);
$key = 20;
$arraySize = sizeof($a);
$count = 0;
for($i = 0; $i < $arraySize; $i++)
{
if($a[$i] <= $key)
{
$count += 1;
}
}
echo "Rank of " . $key . " in stream is: " .
($count - 1) . "\n";
?>
|
Output:
Rank of 20 in stream is: 8
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.