📌  相关文章
📜  最小化数组中的插入,以获取所有总和,直到N

📅  最后修改于: 2021-04-21 21:13:06             🧑  作者: Mango

给定大小为K的正整数和整数N的排序数组arr [] ,可以将一些数字插入到数组中,以便可以将所有正整数[1,N]作为修改后的数组的子集之和获得。任务是找到所需的最小插入次数。
注意:数组的最小长度可以是1。
例子:

方法:此问题可以使用贪婪方法解决。

  1. 通过包括给定数组arr []中的某些元素和/或添加所需的其他缺失元素,形成一个要形成N的总和所需的基本元素X []的列表。
  2. 最初,从空列表X []开始,使用来自X []的数字得出的总和范围为[0,0]。
  3. 假设可以将[1,m] (m X []中存在的元素的总和,并且添加了直到arr []的索引i的数字。 。
    以下是以下可能性:
  1. 重复此过程,直到范围超过给定数字N。
  2. 即使这样做,如果遍历数组arr []中的所有数字,并且范围还没有超过N,那么就需要继续向X []添加越来越多的数字,直到范围超过N。
  3. X []arr []大小之间的差异是所需的最小插入次数
  4. 在将所有基本元素包括在X []中之后,该范围应至少为[1,N],并从给定列表的外部插入最少数量的字符。

注意:计数器变量ans可以初始化为0,而不是维护列表X [],并且每次添加新元素时,计数器值都可以增加。计数器变量的值是必需的答案。
下面是上述方法的实现:

C++
// 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
// 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
# 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#
// 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


输出:
2

时间复杂度: O(K + log(N))