Open In App

Rank the array according to rightmost set bit and least set bits

Last Updated : 16 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N integers, the task is to replace each element of Array with their rank according to Rightmost-Set Bit (RSB) in descending manner, If the RSB is the same for two numbers then choose the one which has the least number of set bits if the set bits of two numbers are same then choose the number who comes first in the array.

Examples:

Input: arr[] = {4, 5, 6, 7, 8}
Output: 2 4 3 5 1
Explanation: Then rank of elements is given by sorted descending of RSB.
Rank(8) = 1 as Rsb of 8(1000) is 8 and setbit count is 1.
Rank(4) = 2 as RSB of 4(0100) is 4 and setbit count is 1.
Rank(6) = 3 as RSB of 6(0110) is 2 and setbit count is 2.
Rank(5) = 4 as RSB of 5(0101) is 1 and setbit count is 2.
Rank(7) = 5 as Rsb of 7(0111) is 1 and setbit count is 3.
So, the answer will be { 2, 4, 3, 5, 1 }.

Input: arr[] = {5, 10, 15, 32}
Output: 3 2 4 1

 

Naive Approach: The naive approach is to find the rank of each element by comparing the RSB of that element with other elements and incrementing the rank by 1 whenever a greater value of RSB is encountered.

Time Complexity: O(N*N).
Auxiliary Space: O(N).

Efficient Approach: To optimize the above naive approach find ranks of elements and then assign the rank to the elements using a comparator. Using a comparator, the elements can be sorted based on data members. For instance, here the elements will be sorted based on the RSB and number of set bits.

Below is the implementation of the above approach.

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Class for pair
class Pair {
    public:
    int index;
    int rsb;
    int setbit;
 
    // Constructor
    Pair(int index, int rsb, int setbit)
     :index(index),rsb(rsb),setbit(setbit)
    {
    }
};
 
// Comparator for sorting based on RSB
bool operator<(const Pair& a, const Pair& b)
    {
        if (a.rsb > b.rsb)
            return false;
        else if (a.rsb < b.rsb)
            return true;
        else if (a.setbit < b.setbit)
            return false;
        else if (b.setbit < a.setbit)
            return true;
        else if (a.index < b.index)
            return false;
        else
            return true;
    }
 
    // Function to rearrange the elements
    // according to Rightmpost set bits
    void rearrange(int ar[], int n)
    {
        // Creating priority queue from
        // sorting according to
        // rightmost set bit.
        priority_queue<Pair> pq;
 
        // For creating object of each element
        // so that it can be sorted
        for (int i = 0; i < n; i++) {
 
            // To calculate the rightmost
            // set bit in O(1)
            int k = (ar[i] & -ar[i]);
 
            // Creating a pair object
            // with rsb and index
            int setbit
                = __builtin_popcount(ar[i]);
 
            // Inserting the element
            // in priorityqueue
            pq.push(Pair(i, k, setbit));
        }
 
        int rank = 1;
        // Popping the element of queue
        // to get respective rank.
        while (!pq.empty()) {
            Pair p = pq.top();
            pq.pop();
            ar[p.index] = rank++;
        }
    }
 
    // Driver code
        int main()
    {
        int arr[] = { 4, 5, 6, 7, 8 };
        // To store the length of array
        int N = sizeof(arr) / sizeof(arr[0]);;
 
        // To call the rearrange function
        rearrange(arr, N);
        for (int i = 0; i < N; i++)
            cout<<arr[i]<<" ";
             
        return 0;
    }
 
// This code is contributed by Pushpesh raj.


Java




// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
// Class for pair
class Pair {
    int index;
    int rsb;
    int setbit;
 
    // Constructor
    Pair(int index, int rsb, int setbit)
    {
        this.index = index;
        this.rsb = rsb;
        this.setbit = setbit;
    }
}
 
// Comparator for sorting based on RSB
class pair_sort implements Comparator<Pair> {
    // Used for sorting in descending order
    // of rightmost set bit
    public int compare(Pair a, Pair b)
    {
        if (a.rsb > b.rsb)
            return -1;
        else if (a.rsb < b.rsb)
            return 1;
        else if (a.setbit < b.setbit)
            return -1;
        else if (b.setbit < a.setbit)
            return 1;
        else if (a.index < b.index)
            return -1;
        else
            return 1;
    }
}
 
// Class to implement the solution logic
class GFG {
 
    // Function to rearrange the elements
    // according to Rightmpost set bits
    void rearrange(int ar[], int n)
    {
        // Creating priority queue from
        // sorting according to
        // rightmost set bit.
        PriorityQueue<Pair> pq
            = new PriorityQueue<Pair>(new pair_sort());
 
        // For creating object of each element
        // so that it can be sorted
        for (int i = 0; i < n; i++) {
 
            // To calculate the rightmost
            // set bit in O(1)
            int k = (ar[i] & -ar[i]);
 
            // Creating a pair object
            // with rsb and index
            int setbit
                = Integer.bitCount(ar[i]);
            Pair p = new Pair(i, k, setbit);
 
            // Inserting the element
            // in priorityqueue
            pq.add(p);
        }
 
        int rank = 1;
        // Popping the element of queue
        // to get respective rank.
        while (!pq.isEmpty()) {
            Pair p = pq.poll();
 
            ar[p.index] = rank++;
        }
    }
 
    // Driver code
    public static void main(String[] args)
        throws java.lang.Exception
    {
        int arr[] = { 4, 5, 6, 7, 8 };
 
        // Creating an object of class
        GFG ob = new GFG();
 
        // To store the length of array
        int N = arr.length;
 
        // To call the rearrange function
        ob.rearrange(arr, N);
        for (int i = 0; i < N; i++)
            System.out.print(arr[i] + " ");
    }
}


Python3




# Python program for the above approach
import heapq
 
# pair class
class Pair:
    def __init__(self, index, rsb, setbit):
        self.index = index
        self.rsb = rsb
        self.setbit = setbit
 
class Soln:
     # Function to rearrange the elements
    # according to Rightmpost set bits
    def rearrng(self, arr: list) -> list:
        n = len(arr)
        pq = []
 
        # Creating a pair object
        # with rsb and index
        for i in range(n):
            # To calculate the rightmost
            # set bit in O(1)
            k = (arr[i] & -arr[i])
             
             # Creating a pair object
            # with rsb and index
            setbit = bin(arr[i]).count('1')
            p = Pair(i, k, setbit)
              #Inserting the element
            #in priorityqueue
            heapq.heappush(pq, (-p.rsb, p.setbit, p.index))
 
        rank = 1
         # Popping the element of queue
        # to get respective rank.
        while pq:
            p = heapq.heappop(pq)
            arr[p[2]] = rank
            rank += 1
 
        return arr
 
# Driver code
arr = [4, 5, 6, 7, 8]
 
# Creating an object of class
ob = Soln()
 
# To call the rearrange function
res = ob.rearrng(arr)
print(res)


Javascript




// Define Priority Queuefor JavaScript as there is no pre-defined in JavaScript
class PriorityQueue {
  constructor() {
    this.heap = [];
    this.comparator = (a, b) => {
      if (a.rsb > b.rsb) {
        return 1;
      } else if (a.rsb < b.rsb) {
        return -1;
      } else if (a.setbit > b.setbit) {
        return 1;
      } else if (a.setbit < b.setbit) {
        return -1;
      } else if (a.index > b.index) {
        return 1;
      } else {
        return -1;
      }
    };
  }
// To insert into queue
  enqueue(value) {
    this.heap.push(value);
    let index = this.heap.length - 1;
    while (index > 0) {
      let parentIndex = Math.floor((index - 1) / 2);
      if (this.comparator(this.heap[parentIndex], this.heap[index]) <= 0) {
        break;
      }
      [this.heap[parentIndex], this.heap[index]] = [
        this.heap[index],
        this.heap[parentIndex],
      ];
      index = parentIndex;
    }
  }
// To pop from queue
  dequeue() {
    if (this.isEmpty()) {
      return undefined;
    }
    if (this.size() === 1) {
      return this.heap.shift();
    }
    const minValue = this.heap[0];
    this.heap[0] = this.heap.pop();
    let index = 0;
    let leftChildIndex = 2 * index + 1;
    let rightChildIndex = 2 * index + 2;
    while (
      (leftChildIndex < this.size() &&
        this.comparator(this.heap[leftChildIndex], this.heap[index]) < 0) ||
      (rightChildIndex < this.size() &&
        this.comparator(this.heap[rightChildIndex], this.heap[index]) < 0)
    ) {
      let smallerIndex =
        rightChildIndex < this.size() &&
        this.comparator(this.heap[rightChildIndex], this.heap[leftChildIndex]) < 0
          ? rightChildIndex
          : leftChildIndex;
      [this.heap[index], this.heap[smallerIndex]] = [
        this.heap[smallerIndex],
        this.heap[index],
      ];
      index = smallerIndex;
      leftChildIndex = 2 * index + 1;
      rightChildIndex = 2 * index + 2;
    }
    return minValue;
  }
// Queue is empty or not
  isEmpty() {
    return this.size() === 0;
  }
 
  size() {
    return this.heap.length;
  }
 
  peek() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.heap[0];
  }
}
 
// Class for pair
class Pair {
  constructor(index, rsb, setbit) {     // Constructor
    this.index = index;
    this.rsb = rsb;
    this.setbit = setbit;
  }
}
 
// Function to rearrange the elements
// according to Rightmpost set bits
function rearrange(arr) {
        // Creating priority queue from
        // sorting according to
        // rightmost set bit.
  const n = arr.length;
  const pq = [];
 
    // For creating object of each element
        // so that it can be sorted
  for (let i = 0; i < n; i++) {
       
      // To calculate the rightmost
            // set bit in O(1)
    const k = (arr[i] & -arr[i]);
     
        // Creating a pair object
            // with rsb and index
    const setbit = arr[i].toString(2).replace(/0/g, '').length;
     
        // Inserting the element
            // in priorityqueue
    pq.push(new Pair(i, k, setbit));
  }
   
// sorting based on RSB
  pq.sort((a, b) => { 
    if (a.rsb > b.rsb) {
      return -1;
    } else if (a.rsb < b.rsb) {
      return 1;
    } else if (a.setbit < b.setbit) {
      return -1;
    } else if (a.setbit > b.setbit) {
      return 1;
    } else if (a.index < b.index) {
      return -1;
    } else {
      return 1;
    }
  });
 
  for (let i = 0; i < n; i++) {
    arr[pq[i].index] = i + 1;
  }
 
  return arr;
}
 
// Driver Code
const arr = [4, 5, 6, 7, 8];
// To call the rearrange function
const res = rearrange(arr);
console.log(res.join(' '));


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
// Class for pair
class Pair : IComparable<Pair>
{
public int index;
public int rsb;
public int setbit;
// Constructor
public Pair(int index, int rsb, int setbit)
{
    this.index = index;
    this.rsb = rsb;
    this.setbit = setbit;
}
 
// Comparator for sorting based on RSB
public int CompareTo(Pair other)
{
    if (this.rsb > other.rsb)
        return -1;
    else if (this.rsb < other.rsb)
        return 1;
    else if (this.setbit < other.setbit)
        return -1;
    else if (other.setbit < this.setbit)
        return 1;
    else if (this.index < other.index)
        return -1;
    else
        return 1;
}
}
// Class to implement the solution logic
class GFG
{
    // Function to rearrange the elements
    // according to Rightmpost set bits
public void rearrange(int[] ar, int n)
{
    // Creating priority queue from
    // sorting according to
    // rightmost set bit.
    SortedSet<Pair> pq = new SortedSet<Pair>();
 
    // For creating object of each element
    // so that it can be sorted
    for (int i = 0; i < n; i++)
    {
        // To calculate the rightmost
        // set bit in O(1)
        int k = (ar[i] & -ar[i]);
        // Creating a pair object
        // with rsb and index
        int setbit = Convert.ToString(ar[i], 2).Length - Convert.ToString(ar[i], 2).Replace("1", "").Length;
        Pair p = new Pair(i, k, setbit);
        // Inserting the element
        // in priorityqueue
        pq.Add(p);
    }
 
    int rank = 1;
    // Popping the element of queue
    // to get respective rank.
    foreach (Pair p in pq)
    {
        ar[p.index] = rank++;
    }
}
 
// Driver code
public static void Main(string[] args)
{
    int[] arr = { 4, 5, 6, 7, 8 };
 
    // Creating an object of class
    GFG ob = new GFG();
 
    // To store the length of array
    int N = arr.Length;
     
    // To call the rearrange function
    ob.rearrange(arr, N);
    for (int i = 0; i < N; i++)
        Console.Write(arr[i] + " ");
}
}
 
// This code is contributed by Aman Kumar.


Output

2 4 3 5 1 

Time Complexity: O(N*log(N))
Auxiliary Space: O(N).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads