Minimize Range of the Array
Last Updated :
31 Jan, 2024
Given an array A of size N. In one operation, you can select any number from the array and reduce it to a divisor greater than 1. For example, you can reduce 16 to 2, 4, 8 or 16. You need to find the minimum range of the array by doing any number of operations on the array. You can do multiple operations on a single element as well. The range of the array is defined as the difference between the maximum element and minimum element of the array.
Examples:
Input: N=3 , A=[2 4 8]
Output: 0
Explanation: We can convert the array into [2, 2, 2]. So the difference between the maximum element and minimum element is zero.
Input: N=3 ,A=[3 8 9]
Output:1
Explanation: We can convert the array into [3, 2, 3]. So the difference between the maximum element and minimum element is one.
Approach: We can solve this problem using the below idea
The first observation is that the duplicate elements does not add any thing to the result. for Example [2, 4, 8, 8] in this example if the first 8 is reduce to 2 likewise the other 8 can also be reduced to 2. The main aim of the problem is to minimize the difference between maximum and minimum element of the array. So in order to minimize the difference, we have two options one is to maximize the minimum element of the array or minimize the maximum element of the array. Lets concentrate on maximize the minimum element of the array. Consider an example of [2, 4, 8]. Listing out the factors ( > 1) of these numbers:
Indexes = [0, 1, 2]
2 = [2]
4 = [2, 4]
8 = [2, 4, 8]
We will keep pick up the minimum element from all of the factors of a particular number and push them into a heap. And will keep track of maximum element in the maximum variable. We will pop the smallest element from the heap now difference the smallest element and maximum element that we have kept track of can be the answer. But if there is another factor for the element we have popped we push the factor into the heap again by doing so we can increase the minimum element of the array. We will continue doing the same procedure until the heap becomes empty. And will return minimum of the all those.
Steps to Solve this problem:
- Find all the factors in the range [2, 104] using sieve.
- Remove all duplicates elements in the array A. By inserting them into a set.
- Initialize a variable maximum to zero. To keep track of the maximum element.
- Initialize a vector startIndexes which will hold the current index of the factor for a particular element in the array.
- Now iterate over the unique sorted elements. Push all the minimum factor for all the elements in the array into a min heap and store maximum of them in variable maximum.
- Initialize a variable ans which will store the final result to difference of maximum and top element in the min heap.
- If the minimum element having some more factors, we move ahead to the next factor in the list. We will pop the top element from the priority queue and add the next factor and according the increment the startIndexes array.
- Continue this procedure until the priority queue becomes empty or there are no more factors exists for top most element.
- Return the final result.
Below is the Implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int NUM = 10e4 + 1;
vector<int> factors[NUM];
// function to find the all factors in the range [2, NUM]
void getFactors()
{
for (int i = 2; i < NUM; i++) {
for (int j = i; j < NUM; j += i) {
factors[j].push_back(i);
}
}
}
// function to find the final answer
int findMinimumRange(int N, vector<int>& A)
{
// get factors of all the numbers in the range [2, NUM]
getFactors();
// to remove duplicates
set<int> s(A.begin(), A.end());
// assign it to vector uniSorted (unique and sorted
// elements)
vector<int> uniSorted(s.begin(), s.end());
N = uniSorted.size();
// Min Heap to hold {factor, index}
// where factor represents the present factor of the
// element uniSorted[index]
priority_queue<pair<int, int>, vector<pair<int, int>>,
greater<pair<int, int>>>
pq;
// to keep track of the maximum element
int maximum = 0;
// to keep track of the indexes of the factors.
vector<int> startIndexes(N + 1, 0);
for (int i = 0; i < N; i++) {
pq.push({ factors[uniSorted[i]][0], i });
maximum = max(maximum, factors[uniSorted[i]][0]);
}
// difference between the maximum and minimum element at
// this point.
int ans = maximum - pq.top().first;
while (!pq.empty()) {
int ind = pq.top().second;
pq.pop();
// break if no more factors are available at index
// ind
if (startIndexes[ind] + 1
== factors[uniSorted[ind]].size())
break;
// move on to the next index and mark it on
// startIndexes
startIndexes[ind] += 1;
pq.push(
{ factors[uniSorted[ind]][startIndexes[ind]],
ind });
maximum = max(
maximum,
factors[uniSorted[ind]][startIndexes[ind]]);
ans = min(ans, maximum - pq.top().first);
}
// return the result
return ans;
}
int main()
{
int N = 3;
vector<int> A = { 3, 9, 8 };
// function call
cout << findMinimumRange(N, A);
}
Java
import java.util.*;
public class Solution {
static final int NUM = 100001; // Constants are similar, but Java arrays start at 0 by default
static List<Integer>[] factors = new ArrayList[NUM];
// function to find all factors in the range [2, NUM]
static void getFactors() {
for (int i = 2; i < NUM; i++) {
for (int j = i; j < NUM; j += i) {
if (factors[j] == null) {
factors[j] = new ArrayList<>();
}
factors[j].add(i);
}
}
}
// function to find the final answer
static int findMinimumRange(int N, List<Integer> A) {
// get factors of all the numbers in the range [2, NUM]
getFactors();
// to remove duplicates
Set<Integer> s = new HashSet<>(A);
// assign it to list uniSorted (unique and sorted elements)
List<Integer> uniSorted = new ArrayList<>(s);
N = uniSorted.size();
// Min Heap to hold {factor, index}
// where factor represents the present factor of the
// element uniSorted[index]
PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>(
Comparator.comparingInt(o -> o.first));
// to keep track of the maximum element
int maximum = 0;
// to keep track of the indexes of the factors.
int[] startIndexes = new int[N + 1];
for (int i = 0; i < N; i++) {
pq.add(new Pair<>(factors[uniSorted.get(i)].get(0), i));
maximum = Math.max(maximum, factors[uniSorted.get(i)].get(0));
}
// difference between the maximum and minimum element at this point.
int ans = maximum - pq.peek().first;
while (!pq.isEmpty()) {
Pair<Integer, Integer> pair = pq.poll();
int ind = pair.second;
// break if no more factors are available at index ind
if (startIndexes[ind] + 1 == factors[uniSorted.get(ind)].size()) {
break;
}
// move on to the next index and mark it on startIndexes
startIndexes[ind] += 1;
pq.add(new Pair<>(factors[uniSorted.get(ind)].get(startIndexes[ind]), ind));
maximum = Math.max(maximum, factors[uniSorted.get(ind)].get(startIndexes[ind]));
ans = Math.min(ans, maximum - pq.peek().first);
}
// return the result
return ans;
}
public static void main(String[] args) {
int N = 3;
List<Integer> A = Arrays.asList(3, 9, 8);
// function call
System.out.println(findMinimumRange(N, A));
}
// Simple Pair class to hold two values
static class Pair<T, U> {
T first;
U second;
Pair(T first, U second) {
this.first = first;
this.second = second;
}
}
}
// This code is contributed by akshitaguprzj3
Python3
# Python Implmentation
import heapq
NUM = 10**4 + 1
factors = [[] for _ in range(NUM)]
# function to find all factors in the range [2, NUM]
def get_factors():
for i in range(2, NUM):
for j in range(i, NUM, i):
factors[j].append(i)
# function to find the final answer
def find_minimum_range(N, A):
# get factors of all numbers in the range [2, NUM]
get_factors()
# remove duplicates
s = set(A)
# assign it to a list uni_sorted (unique and sorted elements)
uni_sorted = sorted(list(s))
N = len(uni_sorted)
# Min Heap to hold (factor, index) where factor represents the present factor
# of the element uni_sorted[index]
pq = []
# to keep track of the maximum element
maximum = 0
# to keep track of the indexes of the factors
start_indexes = [0] * (N + 1)
for i in range(N):
heapq.heappush(pq, (factors[uni_sorted[i]][0], i))
maximum = max(maximum, factors[uni_sorted[i]][0])
# difference between the maximum and minimum element at this point
ans = maximum - pq[0][0]
while pq:
factor, ind = heapq.heappop(pq)
# break if no more factors are available at index ind
if start_indexes[ind] + 1 == len(factors[uni_sorted[ind]]):
break
# move on to the next index and mark it on start_indexes
start_indexes[ind] += 1
heapq.heappush(pq, (factors[uni_sorted[ind]][start_indexes[ind]], ind))
maximum = max(maximum, factors[uni_sorted[ind]][start_indexes[ind]])
ans = min(ans, maximum - pq[0][0])
# return the result
return ans
if __name__ == "__main__":
N = 3
A = [3, 9, 8]
# function call
print(find_minimum_range(N, A))
# This code is contributed by Tapesh(tapeshdua420)
C#
using System;
using System.Collections.Generic;
public class Program
{
const int NUM = 100001;
static List<int>[] factors = new List<int>[NUM];
// Function to find all factors in the range [2, NUM]
public static void GetFactors()
{
for (int i = 0; i < NUM; i++)
{
factors[i] = new List<int>();
}
for (int i = 2; i < NUM; i++)
{
for (int j = i; j < NUM; j += i)
{
factors[j].Add(i);
}
}
}
// Function to find the final answer
public static int FindMinimumRange(int N, List<int> A)
{
// Get factors of all the numbers in the range [2, NUM]
GetFactors();
// Remove duplicates
HashSet<int> s = new HashSet<int>(A);
// Assign it to a list uniSorted (unique and sorted elements)
List<int> uniSorted = new List<int>(s);
N = uniSorted.Count;
// Min Heap to hold {factor, index}
SortedSet<Tuple<int, int>> pq = new SortedSet<Tuple<int, int>>();
// To keep track of the maximum element
int maximum = 0;
// To keep track of the indexes of the factors
int[] startIndexes = new int[N + 1];
for (int i = 0; i < N; i++)
{
pq.Add(Tuple.Create(factors[uniSorted[i]][0], i));
maximum = Math.Max(maximum, factors[uniSorted[i]][0]);
}
// Difference between the maximum and minimum element at this point
int ans = maximum - pq.Min.Item1;
while (pq.Count > 0)
{
var tuple = pq.Min;
pq.Remove(tuple);
int ind = tuple.Item2;
// Break if no more factors are available at index ind
if (startIndexes[ind] + 1 == factors[uniSorted[ind]].Count)
break;
// Move on to the next index and mark it on startIndexes
startIndexes[ind] += 1;
pq.Add(Tuple.Create(factors[uniSorted[ind]][startIndexes[ind]], ind));
maximum = Math.Max(maximum, factors[uniSorted[ind]][startIndexes[ind]]);
ans = Math.Min(ans, maximum - pq.Min.Item1);
}
// Return the result
return ans;
}
public static void Main()
{
int N = 3;
List<int> A = new List<int> { 3, 9, 8 };
// Function call
Console.WriteLine(FindMinimumRange(N, A));
}
}
// This code is contributed by AKSHITAGUPRZJ3
JavaScript
const NUM = 10e4 + 1;
const factors = Array.from({ length: NUM }, () => []);
// Function to find all factors in the range [2, NUM]
function getFactors() {
for (let i = 2; i < NUM; i++) {
for (let j = i; j < NUM; j += i) {
factors[j].push(i);
}
}
}
// Function to find the final answer
function findMinimumRange(N, A) {
// Get factors of all the numbers in the range [2, NUM]
getFactors();
// Remove duplicates
const s = new Set(A);
// Assign unique and sorted elements to the array uniSorted
const uniSorted = Array.from(s).sort((a, b) => a - b);
N = uniSorted.length;
// Min Heap to hold {factor, index}
// where factor represents the present factor of the
// element uniSorted[index]
const pq = new PriorityQueue((a, b) => a[0] - b[0]);
// To keep track of the maximum element
let maximum = 0;
// To keep track of the indexes of the factors.
const startIndexes = new Array(N + 1).fill(0);
for (let i = 0; i < N; i++) {
pq.enqueue([factors[uniSorted[i]][0], i]);
maximum = Math.max(maximum, factors[uniSorted[i]][0]);
}
// Difference between the maximum and minimum element at this point.
let ans = maximum - pq.peek()[0];
while (!pq.isEmpty()) {
const [ind, index] = pq.dequeue();
// Break if no more factors are available at index ind
if (startIndexes[index] + 1 === factors[uniSorted[index]].length) {
break;
}
// Move on to the next index and mark it on startIndexes
startIndexes[index] += 1;
pq.enqueue([factors[uniSorted[index]][startIndexes[index]], index]);
maximum = Math.max(maximum, factors[uniSorted[index]][startIndexes[index]]);
ans = Math.min(ans, maximum - pq.peek()[0]);
}
// Return the result
return ans;
}
// Priority Queue implementation
class PriorityQueue {
constructor(compare) {
this.heap = [];
this.compare = compare;
}
enqueue(value) {
this.heap.push(value);
this.bubbleUp();
}
dequeue() {
const root = this.heap[0];
const last = this.heap.pop();
if (this.heap.length > 0) {
this.heap[0] = last;
this.bubbleDown();
}
return root;
}
peek() {
return this.heap[0];
}
isEmpty() {
return this.heap.length === 0;
}
bubbleUp() {
let index = this.heap.length - 1;
while (index > 0) {
const parentIndex = Math.floor((index - 1) / 2);
if (this.compare(this.heap[index], this.heap[parentIndex]) < 0) {
this.swap(index, parentIndex);
index = parentIndex;
} else {
break;
}
}
}
bubbleDown() {
let index = 0;
while (true) {
const leftChildIndex = 2 * index + 1;
const rightChildIndex = 2 * index + 2;
let smallestChildIndex = index;
if (leftChildIndex < this.heap.length &&
this.compare(this.heap[leftChildIndex], this.heap[smallestChildIndex]) < 0) {
smallestChildIndex = leftChildIndex;
}
if (rightChildIndex < this.heap.length &&
this.compare(this.heap[rightChildIndex], this.heap[smallestChildIndex]) < 0) {
smallestChildIndex = rightChildIndex;
}
if (smallestChildIndex !== index) {
this.swap(index, smallestChildIndex);
index = smallestChildIndex;
} else {
break;
}
}
}
swap(i, j) {
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
}
}
// Example usage
const N = 3;
const A = [3, 9, 8];
// Function call
console.log(findMinimumRange(N, A));
Time Complexity: O(NlogN). Where N is the number of elements of the array
Auxiliary space: O(N * sqrt(N)), Where N is the number of elements of the array.
Similar Reads
Maximize the cost of reducing array elements
Given an array arr[] of N positive integers. We can choose any one index(say K) of the array and reduce all the elements of the array from index 0 to K - 1 by 1. The cost of this operation is K. If at any index(say idx) element is reduced to 0 then we can't perform this operation in the range [idx,
6 min read
Minimize the value of Z/K
Given two positive integers N (N>1) and K, the task is to output such permutation and the minimum value of Z/K, considering the below conditions: A[ i ] â i for (1 <= i <= N) Value of Z/K is minimized, Where Z = âA[ i ] % i for (1 <= i <= N) Examples: Input: N = 2, K = 1Output: Permut
5 min read
Minimize the sum of MEX by removing all elements of array
Given an array of integers arr[] of size N. You can perform the following operation N times: Pick any index i, and remove arr[i] from the array and add MEX(arr[]) i.e., Minimum Excluded of the array arr[] to your total score. Your task is to minimize the total score. Examples: Input: N = 8, arr[] =
7 min read
Minimizing Array sum with groupings
Given an array arr[] of integers, the task is to minimize its sum by creating groups of up to size k. Each group consists of k elements selected from the array such that the sum of the group is k times the minimum value among the chosen elements (k*min(arr1, arr2, ___, arrk), where arr1, arr2___, ar
7 min read
Minimum sum of product of two arrays
Find the minimum sum of Products of two arrays of the same size, given that k modifications are allowed on the first array. In each modification, one array element of the first array can either be increased or decreased by 2.Examples: Input : a[] = {1, 2, -3} b[] = {-2, 3, -5} k = 5 Output : -31 Exp
14 min read
Minimize Sum of an Array by at most K reductions
Given an array of integers arr[] consisting of N integers, the task is to minimize the sum of the given array by performing at most K operations, where each operation involves reducing an array element arr[i] to floor(arr[i]/2). Examples : Input: N = 4, a[] = {20, 7, 5, 4}, K = 3 Output: 17 Explanat
12 min read
Minimize transfer operations to get the given Array sum
Given two integer arrays A[] and B[] of length N and M respectively, the task is to find the minimum number of operations required such that the sum of elements in array A becomes targetSum. In one operation you can transfer an element from A[] to B[] or from B[] to A[]. Examples Input: N = 4, M = 3
15+ min read
Minimum in a Sorted and Rotated Array
Given a sorted array of distinct elements arr[] of size n that is rotated at some unknown point, the task is to find the minimum element in it. Examples: Input: arr[] = [5, 6, 1, 2, 3, 4]Output: 1Explanation: 1 is the minimum element present in the array.Input: arr[] = [3, 1, 2]Output: 1Explanation:
9 min read
Minimize the non-zero elements in the Array by given operation
Given an array arr[] of length N, the task is to minimize the count of the number of non-zero elements by adding the value of the current element to any of its adjacent element and subtracting from the current element at most once.Examples: Input: arr[] = { 1, 0, 1, 0, 0, 1 } Output: 2 Explanation:
5 min read
Minimize Array size by replacing adjacent integers by their Modulo
Given an array arr[] of positive integers of size N, the task is to find the minimum possible size of the array that can be obtained by replacing any two adjacent positive elements with their modulo i.e., (arr[i]%arr[i+1] or arr[i+1]%arr[i]). Examples: Input: arr[] = {3, 4, 5, 2, 1}Output: 1Explanat
6 min read