Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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;
}


Java




import java.util.*;
  
public class GFG {
  
    static boolean Primes[] = new boolean[500002];
    static ArrayList<Integer> Factors = new ArrayList<>();
  
    static class Pair {
  
        int first;
        int second;
  
        Pair(int i, int j)
        {
            first = i;
            second = j;
        }
    }
  
    // Function to compute Sieve of Eratosthenes
    static void SieveOfEratosthenes(int n)
    {
        Primes[0] = true;
        for (int i = 3; i <= n; i += 2) {
            if (!Primes[i / 2]) {
                for (int j = 3 * i; j <= n; j += 2 * i)
                    Primes[j / 2] = true;
            }
        }
  
        for (int i = 2; i <= 500001; i++) {
            if (!Primes[i])
                Factors.add(i);
        }
    }
  
    // Function to find any log(a) base b
    static int log_a_to_base_b(int a, int b)
    {
        return (int)(Math.log(a) / Math.log(b));
    }
  
    // Function to find the Highest Power
    // of K which divides N
    static 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)(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
    static void displayHighestOrder(int arr[], int N)
    {
        List<Pair> Nums = new ArrayList<>();
  
        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 (int 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 = Math.max(
                        temp, HighestPower(arr[i], Prime));
            }
            Nums.add(new Pair(arr[i], temp));
        }
  
        Collections.sort(Nums,
                         (a, b) -> b.second - a.second);
  
        for (int i = 0; i < N; i++) {
            System.out.print(Nums.get(i).first + " ");
        }
        System.out.println();
    }
  
    public static void main(String[] args)
    {
  
        SieveOfEratosthenes(500000);
  
        int arr[] = { 81, 25, 27, 32, 51 };
  
        int N = arr.length;
  
        // Function Call
        displayHighestOrder(arr, N);
    }
}
  
// This code is contributed by aadityapburujwale.


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.


C#




using System;
using System.Collections.Generic;
  
public class GFG {
    static bool[] Primes = new bool[500002];
    static List<int> Factors = new List<int>();
  
    class Pair {
        public int first;
        public int second;
  
        public Pair(int i, int j)
        {
            first = i;
            second = j;
        }
    }
  
    // Function to compute Sieve of Eratosthenes
    static void SieveOfEratosthenes(int n)
    {
        Primes[0] = true;
        for (int i = 3; i <= n; i += 2) {
            if (!Primes[i / 2]) {
                for (int j = 3 * i; j <= n; j += 2 * i)
                    Primes[j / 2] = true;
            }
        }
  
        for (int i = 2; i <= 500001; i++) {
            if (!Primes[i])
                Factors.Add(i);
        }
    }
  
    // Function to find any log(a) base b
    static int log_a_to_base_b(int a, int b)
    {
        return (int)(Math.Log(a) / Math.Log(b));
    }
  
    // Function to find the Highest Power
    // of K which divides N
    static 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)(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
    static void displayHighestOrder(int[] arr, int N)
    {
        List<Pair> Nums = new List<Pair>();
  
        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;
            foreach(int 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;
                else if (arr[i] % Prime == 0)
                    temp = Math.Max(
                        temp, HighestPower(arr[i], Prime));
            }
            Nums.Add(new Pair(arr[i], temp));
        }
  
        Nums.Sort((a, b) = > b.second - a.second);
  
        for (int i = 0; i < N; i++) {
            Console.Write(Nums[i].first + " ");
        }
        Console.WriteLine();
    }
  
    static public void Main()
    {
        SieveOfEratosthenes(500000);
  
        int[] arr = { 81, 25, 27, 32, 51 };
  
        int N = arr.Length;
  
        // Function Call
        displayHighestOrder(arr, N);
    }
}
  
// This code is contributed by akashish__


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)

 



Last Updated : 24 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads