Open In App

Minimize the size of Array by doing maximum absorptions

Last Updated : 08 Apr, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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*4

No 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++




// 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




// 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




# 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#




// 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


Javascript




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


Output

5

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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads