Open In App

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




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




# 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




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




<script>
 
// JavaScript code to minimize insertions
// such that sum of subsets of
// array elements form all numbers
// up to N
 
      let N = 100005;
       
     function minInsertions(v, n)
    {
       
        // initialised rangeEnd which
        // denotes the range covered,
        // [1, rangeEnd] ans denotes
        // the number of insertions made
        // so far
        let rangeEnd = 0, ans = 0;
        for (let 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
 
        // the size of the given array
        let k = 4;
       
        // the given number n
        let n = 15;
        let v = [ 1, 6, 7, 9 ];
        document.write(minInsertions(v, n));
           
</script>

Output: 
2

 

Time Complexity: O(K + log(N)) 
Auxiliary Space: O(1) because it is using constant space for variables


Article Tags :