Given an array A consisting of N integers and an integer K, the task is to minimize the length of array A, by applying absorptions any number of times, such that:
- Any element in A (A[i]) can absorb any other element in A (A[j]), if it is at least K times the other, i.e. A[i] >= K*A[j].
- If an element X is absorbed by any other element Y, then Y is removed from the array and can not be absorbed by any other element. However, the value of X remains the same.
Examples:
Input: N = 8, K = 2, A = {2, 5, 7, 6, 9, 8, 2, 4}
Output: 5
Explanation: Following are the absorptions done and accordingly changes in the array:
{2, 5, 7, 6, 9, 8, 2, 4} -> {5, 7, 6, 9, 8, 2, 4}: 2 is absorbed by 5, as 5>= 2*2
{5, 7, 6, 9, 8, 2, 4} -> {5, 7, 6, 9, 8, 4}: 2 is absorbed by 8, as 8>= 2*2
{5, 7, 6, 9, 8, 4} -> {5, 7, 6, 9, 8}: 4 is absorbed by 9, as 9>=2*4No further absorptions are possible and final size of the array becomes 5. It can be checked that if absorptions are done in some other way, the size of final array would be more than or equal to 5. Hence, the minimal possible size would be 5.
Input: N=5, K=4, A={10, 11, 12, 13, 14}
Output: 5
Approach: The problem can be solved by a two-pointer approach:
Observations:
- The minimum possible size of final array can be N/2 (the case in which each element either absorbs another element or gets absorbed by another element).
- To perform the absorption process optimally, we can divide the array into two halves such that first half contain smaller elements and second half contains greater elements and greedily perform maximum absorptions.
Follow the below steps to solve this problem:
- Sort the given array.
- Initialize two variables say i and j, that point to first elements of 1st and 2nd half of the array respectively.
- If K times of the element at i is less than the element at j , then decrement the size of the array by 1 (as A[i] would be absorbed by A[j]). Also, increment i and j by 1.
- If not so, that means we need a greater integer to absorb integer at i, so we increment j by 1.
- After completion of iteration, return the size of array.
Following is the code based on above approach:
// C++ program for Minimize the size // of the array by doing maximum absorptions #include <bits/stdc++.h> using namespace std;
// function to find the minimum size of // the array by doing maximum absorptions int minimumSize( int N, int K, int A[])
{ // sorting the given array
sort(A, A + N);
// initializing two variables i and j,
// i iterates through the first half
// of A and j iterates through the
// second half of A
int i = 0, j = (N + 1) / 2;
// variable to store minimum size of
// array after doing maximum absorptions.
// Initially, size of array is N
int answer = N;
// iterating the array through 2
// pointers(i and j)
while (i < (N + 1) / 2 && j < N) {
// num1 and num2 stores the value of
// elements at indices i and j in
// sorted array A. Obviously,
// num1<=num2
int num1 = A[i];
int num2 = A[j];
// checking if num2 can absorb num1
if (K * num1 <= num2) {
// if num1 is absorbed by num2,
// we increment i and j by 1 and
// decrement the size of array
// (stored in answer) by 1
i++;
j++;
answer--;
}
// since num2 can not absorb num1,
// that means we need a greater integer
// to absorb num1, so we increment
// j by 1
else {
j++;
}
}
// returning the answer
return answer;
} // Driver Code int main()
{ int N = 8, K = 2;
int A[] = { 2, 5, 7, 6, 9, 8, 2, 4 };
int minimum_size = minimumSize(N, K, A);
cout << minimum_size;
} |
// Java program for Minimize the size // of the array by doing maximum absorptions import java.io.*;
import java.util.Arrays;
class GFG {
// function to find the minimum size of
// the array by doing maximum absorptions
static int minimumSize( int N, int K, int A[])
{
// sorting the given array
Arrays.sort(A);
// initializing two variables i and j,
// i iterates through the first half
// of A and j iterates through the
// second half of A
int i = 0 , j = (N + 1 ) / 2 ;
// variable to store minimum size of
// array after doing maximum absorptions.
// Initially, size of array is N
int answer = N;
// iterating the array through 2
// pointers(i and j)
while (i < (N + 1 ) / 2 && j < N) {
// num1 and num2 stores the value of
// elements at indices i and j in
// sorted array A. Obviously,
// num1<=num2
int num1 = A[i];
int num2 = A[j];
// checking if num2 can absorb num1
if (K * num1 <= num2) {
// if num1 is absorbed by num2,
// we increment i and j by 1 and
// decrement the size of array
// (stored in answer) by 1
i++;
j++;
answer--;
}
// since num2 can not absorb num1,
// that means we need a greater integer
// to absorb num1, so we increment
// j by 1
else {
j++;
}
}
// returning the answer
return answer;
}
// Driver Code
public static void main (String[] args) {
int N = 8 , K = 2 ;
int A[] = { 2 , 5 , 7 , 6 , 9 , 8 , 2 , 4 };
int minimum_size = minimumSize(N, K, A);
System.out.println(minimum_size);
}
} // This code is contributed by hrithikgarg03188. |
# Python3 program to implement the above approach # function to find the minimum size of # the array by doing maximum absorptions def minimumSize(N, K, A):
# sorting the given array
A.sort()
# initializing two variables i and j,
# i iterates through the first half
# of A and j iterates through the
# second half of A
i = 0
j = (N + 1 ) / / 2
# variable to store minimum size of
# array after doing maximum absorptions.
# Initially, size of array is N
answer = N
# iterating the array through 2
#pointers(i and j)
while (i < (N + 1 ) / 2 and j < N):
'''num1 and num2 stores the value of
elements at indices i and j in
sorted array A. Obviously,
num1<=num2'''
num1 = A[i]
num2 = A[j]
# checking if num2 can absorb num1
if K * num1 < = num2:
# if num1 is absorbed by num2,
# we increment i and j by 1 and
# decrement the size of array
# (stored in answer) by 1
i + = 1
j + = 1
answer - = 1
else :
# since num2 can not absorb num1,
# that means we need a greater integer
# to absorb num1, so we increment
# j by 1
j + = 1
return answer
# Driver Code N = 8
K = 2
A = [ 2 , 5 , 7 , 6 , 9 , 8 , 2 , 4 ]
minimum_size = minimumSize(N, K, A)
print (minimum_size)
# This code is contributed by phasing17 |
// C# program for Minimize the size // of the array by doing maximum absorptions using System;
using System.Collections.Generic;
class GFG
{ // function to find the minimum size of
// the array by doing maximum absorptions
static int minimumSize( int N, int K, int [] A)
{
// sorting the given array
Array.Sort(A);
// initializing two variables i and j,
// i iterates through the first half
// of A and j iterates through the
// second half of A
int i = 0;
int j = (N + 1) / 2;
// variable to store minimum size of
// array after doing maximum absorptions.
// Initially, size of array is N
int answer = N;
// iterating the array through 2
// pointers(i and j)
while ((i < (N + 1) / 2) && (j < N))
{
// num1 and num2 stores the value of
// elements at indices i and j in
// sorted array A. Obviously,
// num1<=num2
var num1 = A[i];
var num2 = A[j];
// checking if num2 can absorb num1
if ((K * num1) <= num2)
{
// if num1 is absorbed by num2,
// we increment i and j by 1 and
// decrement the size of array
// (stored in answer) by 1
i++;
j++;
answer--;
}
// since num2 can not absorb num1,
// that means we need a greater integer
// to absorb num1, so we increment
// j by 1
else
j++;
}
// returning the answer
return answer;
}
static void Main()
{
// Driver Code
var N = 8;
var K = 2;
int [] A = { 2, 5, 7, 6, 9, 8, 2, 4 };
int minimum_size = minimumSize(N, K, A);
Console.Write(minimum_size);
}
} // This code is contributed by phasing17 |
<script> // JavaScript code for the above approach
// function to find the minimum size of
// the array by doing maximum absorptions
function minimumSize(N, K, A)
{
// sorting the given array
A.sort( function (a, b) { return a - b })
// initializing two variables i and j,
// i iterates through the first half
// of A and j iterates through the
// second half of A
let i = 0, j = Math.floor((N + 1) / 2);
// variable to store minimum size of
// array after doing maximum absorptions.
// Initially, size of array is N
let answer = N;
// iterating the array through 2
// pointers(i and j)
while (i < (N + 1) / 2 && j < N)
{
// num1 and num2 stores the value of
// elements at indices i and j in
// sorted array A. Obviously,
// num1<=num2
let num1 = A[i];
let num2 = A[j];
// checking if num2 can absorb num1
if (K * num1 <= num2)
{
// if num1 is absorbed by num2,
// we increment i and j by 1 and
// decrement the size of array
// (stored in answer) by 1
i++;
j++;
answer--;
}
// since num2 can not absorb num1,
// that means we need a greater integer
// to absorb num1, so we increment
// j by 1
else {
j++;
}
}
// returning the answer
return answer;
}
// Driver Code
let N = 8, K = 2;
let A = [2, 5, 7, 6, 9, 8, 2, 4];
let minimum_size = minimumSize(N, K, A);
document.write(minimum_size);
// This code is contributed by Potta Lokesh
</script>
|
5
Time Complexity: O(N*log(N))
Auxiliary Space: O(1)