Minimize insertions in an array to obtain all sums upto N

Given a sorted array arr[] of positive integers of size K, and an integer N, where some numbers can be inserted into the array such that all positive integers [1, N] can be obtained as a sum of subsets of the modified array. The task is to find the minimum number of insertions required. 
Note: Minimum length of the array can be 1.
Examples: 
 

Input: K = 2, arr = [1, 2], N = 4 
Output:
Explanation We need to insert either 3 or 4 in the array.
Input: K = 4, arr = [1, 2, 4, 8], N = 15 
Output:
 

 

Approach: This problem can be solved using Greedy Approach
 

  1. Form a list say X[] of essential elements needed to form a sum up to N by including some elements from the given array arr[] and/or adding other missing elements that are required.
  2. Initially, begin with the empty list X[], the range of possible sums using numbers from X[] is [0, 0].
  3. Suppose that the elements in the range [1, m] (m < N) can be represented as a sum of the elements present in the list X[] at that instant, and numbers till index i of the arr[] have been added. 
    Below are the following possibilities: 
     
  • If the (i+1)th number of arr[] is = (m + 1), then the extra sums possible are: 
    (m + 1), (m + 2), (m + 3)…, (m + m + 1). 
    Hence, the range becomes [1, ((2 * m) + 1)]. Add the number arr[i+1] to X[]. Increment the value of i.
  • If the (i+1)th number of arr[] is < (m + 1), let it be k, then extra sums possible are: 
    (1 + k), (2 + k), (3 + k), …(m + k). 
    Hence, the range becomes [1, (m + k)]. Add the number arr[i+1] to X[] Increment the value of i.
  • If the (i+1)th number of arr[] is > (m + 1), then (m + 1) should be inserted to the array X[], else there is no way to obtain a sum of (m + 1) by these numbers. 
    Hence, the range becomes [1, ((2 * m) + 1)] after insertion of (m + 1). Do not increment the value of i.
  1.  
  2. Repeat this process until the range crosses the given number N.
  3. Even after doing so, if all the numbers in the array arr[] are traversed, and the range hasn’t crossed N, then there is a need to keep on adding more and more numbers to X[] till the range crosses N.
  4. The difference between the sizes of X[] and arr[] is the required minimum number of insertions to be made.
  5. After including all the essential elements in X[] the range should be at least [1, N] with a minimum number of insertions from outside the given list.

Note: Instead of maintaining a list X[], a counter variable ans can be initialised to 0 and everytime a new element is added the counter value can be incremented. The value of the counter variable is the required answer.
Below is the implementation of the above approach: 
 



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to minimize insertions
// such that sum of subsets of
// array elements form all numbers
// up to N
#include <bits/stdc++.h>
using namespace std;
  
#define N 100005
  
int minInsertions(vector<int>& v, int n)
{
  
    // initialised rangeEnd which
    // denotes the range covered,
    // [1, rangeEnd] ans denotes
    // the number of insertions made
    // so far
    int rangeEnd = 0, ans = 0;
    for (auto i : v) {
  
        // in the case where our next
        // number is greater than
        // rangeEnd+1, it is compulsory
        // to insert rangeEnd+1
        while (i > rangeEnd + 1) {
  
            ans++;
            rangeEnd = rangeEnd * 2 + 1;
            if (rangeEnd >= n) {
                return ans;
            }
        }
  
        // otherwise we just move
        // forward our rangeEnd
        rangeEnd += i;
        if (rangeEnd >= n) {
            return ans;
        }
    }
  
    // after we have included all
    // elements in the array and have
    // still not reached n, we insert
    // numbers = rangeEnd+1 till
    // we reach n
    while (rangeEnd < n) {
        ans++;
        rangeEnd = rangeEnd * 2 + 1;
    }
    return ans;
}
  
// Driver Program
signed main()
{
    // the size of the given array
    int k = 4;
  
    // the given number n
    int n = 15;
    std::vector<int> v = { 1, 6, 7, 9 };
    cout << minInsertions(v, n);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java code to minimize insertions 
// such that sum of subsets of 
// array elements form all numbers 
// up to N 
class GFG
{
      int N = 100005;
      
    static int minInsertions(int []v, int n) 
    
      
        // initialised rangeEnd which 
        // denotes the range covered, 
        // [1, rangeEnd] ans denotes 
        // the number of insertions made 
        // so far 
        int rangeEnd = 0, ans = 0
        for (int i : v)
        
      
            // in the case where our next 
            // number is greater than 
            // rangeEnd+1, it is compulsory 
            // to insert rangeEnd+1 
            while (i > rangeEnd + 1
            
                ans++; 
                rangeEnd = rangeEnd * 2 + 1
                if (rangeEnd >= n)
                
                    return ans; 
                
            
      
            // otherwise we just move 
            // forward our rangeEnd 
            rangeEnd += i; 
            if (rangeEnd >= n)
            
                return ans; 
            
        
      
        // after we have included all 
        // elements in the array and have 
        // still not reached n, we insert 
        // numbers = rangeEnd+1 till 
        // we reach n 
        while (rangeEnd < n)
        
            ans++; 
            rangeEnd = rangeEnd * 2 + 1
        
        return ans; 
    
      
    // Driver Program 
    public static void main (String[] args)
    
        // the size of the given array 
        int k = 4
      
        // the given number n 
        int n = 15
        int v[] = { 1, 6, 7, 9 }; 
        System.out.println(minInsertions(v, n)); 
    
}
  
// This code is contributed by AnkitRai01

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to minimize insertions
# such that sum of subsets of
# array elements form all numbers
# up to N
N = 100005
    
def minInsertions(v, n):
   
    # Initialised rangeEnd which
    # denotes the range covered,
    # [1, rangeEnd] ans denotes
    # the number of insertions made
    # so far
    rangeEnd, ans = 0, 0
    for i in v:
    
        # In the case where our next
        # number is greater than
        # rangeEnd+1, it is compulsory
        # to insert rangeEnd+1
        while (i > rangeEnd + 1):
            ans += 1
            rangeEnd = rangeEnd * 2 + 1
            if (rangeEnd >= n):
                return ans
    
        # Otherwise we just move
        # forward our rangeEnd
        rangeEnd += i
        if (rangeEnd >= n):
            return ans
    
    # After we have included all
    # elements in the array and have
    # still not reached n, we insert
    # numbers = rangeEnd+1 till
    # we reach n
    while (rangeEnd < n):
        ans += 1
        rangeEnd = rangeEnd * 2 + 1
    return ans
    
# Driver code
if __name__ == "__main__":
       
    # The size of the given array
    k = 4
    
    # The given number n
    n = 15
    v = [ 1, 6, 7, 9 ]
  
    print(minInsertions(v, n))
  
# This code is contributed by chitranayal

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to minimize insertions 
// such that sum of subsets of 
// array elements form all numbers 
// up to N 
using System;
  
class GFG{
  
//int N = 100005;
      
static int minInsertions(int []v, int n) 
      
    // Initialised rangeEnd which 
    // denotes the range covered, 
    // [1, rangeEnd] ans denotes 
    // the number of insertions made 
    // so far 
    int rangeEnd = 0, ans = 0; 
      
    foreach(int i in v)
    
          
        // In the case where our next 
        // number is greater than 
        // rangeEnd+1, it is compulsory 
        // to insert rangeEnd+1 
        while (i > rangeEnd + 1) 
        
            ans++; 
            rangeEnd = rangeEnd * 2 + 1; 
            if (rangeEnd >= n)
            
                return ans; 
            
        
      
        // Otherwise we just move 
        // forward our rangeEnd 
        rangeEnd += i; 
        if (rangeEnd >= n)
        
            return ans; 
        
    
      
    // After we have included all 
    // elements in the array and have 
    // still not reached n, we insert 
    // numbers = rangeEnd+1 till 
    // we reach n 
    while (rangeEnd < n)
    
        ans++; 
        rangeEnd = rangeEnd * 2 + 1; 
    
    return ans; 
      
// Driver code 
public static void Main(String[] args)
      
    // The size of the given array 
    //int k = 4; 
      
    // The given number n 
    int n = 15; 
    int []v = { 1, 6, 7, 9 }; 
      
    Console.WriteLine(minInsertions(v, n)); 
}
  
// This code is contributed by Rajput-Ji

chevron_right


Output:

2

Time Complexity: O(K + log(N)) 

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : chitranayal, Rajput-Ji

Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.