Skip to content
Related Articles

Related Articles

Sort given Array in descending order according to highest power of prime factors

View Discussion
Improve Article
Save Article
Like Article
  • Difficulty Level : Medium
  • Last Updated : 06 Jan, 2022

Given an array arr[] of size N. The task is to sort the elements in arr[] based to their Highest Degree of Expression, in descending order. The Highest Degree of a number is defined as the maximum value in which it can be expressed as the power of its factors. 

Note: 

  • If the numbers have the same degree of expression the element coming first in the original array will come first in the sorted array.
  • If two numbers have the same highest degree, then the First-Come-First-Serve approach should be used.

Examples:

Input: arr[] = {81, 25, 27, 32, 51}
Output: [32, 81, 27, 25, 51]
Explanation: After prime factorization
81 can be represented as 811, 92, or 34. For the highest degree of expression, choose (3)4 because 4 is greater than 2 and 1.
25 can be represented as 52.
27 can be represented as 33.
32 can be represented as 25
51 can be represented as 511.
Now, sort them in descending order based on their power.
Therefore, 32 comes first since 25 has the highest power, followed by 81, 27, 25, and finally 51 with a power of 1.

Input: arr[] = {23, 6}
Output: [23, 6]
Explanation: Since 23 and 6 both have the same power(1), we print 23 which comes first, followed by 6.

 

Approach: This problem can be solved by using Prime Factorization. Follow the steps below to solve the given problem.

  • The highest power of a number can be obtained by breaking it into a product of its prime factors.
  • Choose the factor which has the highest power among those factors.
  • Store the highest power of a number along with that number in a pair and sort that pair based on the highest power of its factors.
  • Pre-compute all the prime numbers up to 10^5 using the Sieve of Eratosthenes method.
  • For each number in the array, find all the factors of that number and store the highest power of its factor along with that number in a vector of pair of integers.
  • Sort that pair in descending based on the second element(The Highest Order of Expression).

Below is the implementation of the above approach.

C++




// C++ code to implement the above approach
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
bitset<500001> Primes;
vector<int> Factors;
 
// Function to compute Sieve of Eratosthenes
void SieveOfEratosthenes(int n)
{
    Primes[0] = 1;
    for (int i = 3; i <= n; i += 2) {
        if (Primes[i / 2] == 0) {
            for (int j = 3 * i; j <= n; j += 2 * i)
                Primes[j / 2] = 1;
        }
    }
 
    for (int i = 2; i <= 500001; i++) {
        if (!Primes[i])
            Factors.push_back(i);
    }
}
 
// Compare function for sorting
bool compare(const pair<int, int>& a,
             const pair<int, int>& b)
{
    return a.second > b.second;
}
 
// Function to find any log(a) base b
int log_a_to_base_b(int a, int b)
{
    return log(a) / log(b);
}
 
// Function to find the Highest Power
// of K which divides N
int HighestPower(int N, int K)
{
    int start = 0, end = log_a_to_base_b(N, K);
    int ans = 0;
    while (start <= end) {
 
        int mid = start + (end - start) / 2;
        int temp = (int)(pow(K, mid));
 
        if (N % temp == 0) {
            ans = mid;
            start = mid + 1;
        }
        else {
            end = mid - 1;
        }
    }
    return ans;
}
 
// Function to display N numbers
// on the basis of their Highest Order
// of Expression in descending order
void displayHighestOrder(int arr[], int N)
{
    vector<pair<int, int> > Nums;
 
    for (int i = 0; i < N; i++) {
 
        // The least power of a number
        // will always be 1 because
        // that number raised to
        // the power 1 is it itself
        int temp = 1;
        for (auto& Prime : Factors) {
 
            // The factor of a number greater than
            // its square root is the number itself
            // which is considered in temp
            if (Prime * Prime > arr[i])
                break;
            else if (arr[i] % Prime == 0)
                temp = max(
                    temp,
                    HighestPower(arr[i], Prime));
        }
        Nums.push_back(make_pair(arr[i], temp));
    }
 
    sort(Nums.begin(), Nums.end(), compare);
 
    for (int i = 0; i < N; i++) {
        cout << Nums[i].first << " ";
    }
    cout << endl;
}
 
// Driver Code
int main()
{
 
    SieveOfEratosthenes(500000);
 
    int arr[] = { 81, 25, 27, 32, 51 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    displayHighestOrder(arr, N);
 
    return 0;
}

Python3




# Python code for the above approach
import math as Math
 
Primes = [0] * 500001
Factors = []
 
# Function to compute Sieve of Eratosthenes
def SieveOfEratosthenes(n):
    Primes[0] = 1
    for i in range(3, n + 1, 2):
        if (Primes[i // 2] == 0):
            for j in range(3 * i, n + 1, 2 * i):
                Primes[j // 2] = 1
 
    for i in range(2, 500001) :
        if (not Primes[i]):
            Factors.append(i)
     
# Compare function for sorting
def compare(a, b):
    return b.second - a.second
 
# Function to find any log(a) base b
def log_a_to_base_b(a, b):
    return Math.log(a) / Math.log(b)
 
# Function to find the Highest Power
# of K which divides N
def HighestPower(N, K):
    start = 0
    end = log_a_to_base_b(N, K)
    ans = 0
    while (start <= end):
 
        mid = start + Math.floor((end - start) / 2)
        temp = (Math.pow(K, mid))
 
        if (N % temp == 0):
            ans = mid
            start = mid + 1
        else:
            end = mid - 1
    return ans
 
# Function to display N numbers
# on the basis of their Highest Order
# of Expression in descending order
def displayHighestOrder(arr, N):
    Nums = []
 
    for i in range(N):
 
        # The least power of a number
        # will always be 1 because
        # that number raised to
        # the power 1 is it itself
        temp = 1
        for Prime in Factors:
 
            # The factor of a number greater than
            # its square root is the number itself
            # which is considered in temp
            if (Prime * Prime > arr[i]):
                break
            elif (arr[i] % Prime == 0):
                temp = max( temp, HighestPower(arr[i], Prime))
        Nums.append({"first": arr[i], "second": temp})
     
 
    Nums = sorted(Nums, key=lambda l: l["second"], reverse=True)
 
    for i in range(N):
        print(Nums[i]["first"], end= " ")
    print('')
 
# Driver Code
SieveOfEratosthenes(500000)
arr = [81, 25, 27, 32, 51]
N = len(arr)
 
# Function Call
displayHighestOrder(arr, N)
 
# This code is contributed by gfgking.

Javascript




<script>
      // JavaScript code for the above approach
      let Primes = new Array(500001);
      let Factors = [];
 
      // Function to compute Sieve of Eratosthenes
      function SieveOfEratosthenes(n) {
          Primes[0] = 1;
          for (let i = 3; i <= n; i += 2) {
              if (Primes[Math.floor(i / 2)] == 0) {
                  for (let j = 3 * i; j <= n; j += 2 * i)
                      Primes[Math.floor(j / 2)] = 1;
              }
          }
 
          for (let i = 2; i <= 500001; i++) {
              if (!Primes[i])
                  Factors.push(i);
          }
      }
 
      // Compare function for sorting
      function compare(a,
          b) {
          return b.second - a.second;
      }
 
      // Function to find any log(a) base b
      function log_a_to_base_b(a, b) {
          return Math.log(a) / Math.log(b);
      }
 
      // Function to find the Highest Power
      // of K which divides N
      function HighestPower(N, K) {
          let start = 0, end = log_a_to_base_b(N, K);
          let ans = 0;
          while (start <= end) {
 
              let mid = start + Math.floor((end - start) / 2);
              let temp = (Math.pow(K, mid));
 
              if (N % temp == 0) {
                  ans = mid;
                  start = mid + 1;
              }
              else {
                  end = mid - 1;
              }
          }
          return ans;
      }
 
      // Function to display N numbers
      // on the basis of their Highest Order
      // of Expression in descending order
      function displayHighestOrder(arr, N) {
          let Nums = [];
 
          for (let i = 0; i < N; i++) {
 
              // The least power of a number
              // will always be 1 because
              // that number raised to
              // the power 1 is it itself
              let temp = 1;
              for (Prime of Factors) {
 
                  // The factor of a number greater than
                  // its square root is the number itself
                  // which is considered in temp
                  if (Prime * Prime > arr[i])
                      break;
                  else if (arr[i] % Prime == 0)
                      temp = Math.max(
                          temp,
                          HighestPower(arr[i], Prime));
              }
              Nums.push({ first: arr[i], second: temp });
          }
 
          Nums.sort(compare)
 
          for (let i = 0; i < N; i++) {
              document.write(Nums[i].first + " ");
          }
          document.write('<br>')
      }
 
      // Driver Code
      SieveOfEratosthenes(500000);
      let arr = [81, 25, 27, 32, 51];
      let N = arr.length;
 
      // Function Call
      displayHighestOrder(arr, N);
 
// This code is contributed by Potta Lokesh
  </script>

Output

32 81 27 25 51 

Time Complexity: O(N1.5 *log(K)), Where K is the maximum element in the array.
Auxiliary Space: O(1)

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!