# 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 using namespace std;    #define N 100005    int minInsertions(vector& 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 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

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.

Article Tags :
Practice Tags :