📌  相关文章
📜  添加到 arr[i] 的最小值,以便可以在索引 i 处以相等的总和拆分数组

📅  最后修改于: 2022-05-13 01:57:50.392000             🧑  作者: Mango

添加到 arr[i] 的最小值,以便可以在索引 i 处以相等的总和拆分数组

给定一个整数数组arr[] ,任务是找到最小非负整数k使得给定数组中存在索引j使得当arr[j]更新为arr[j] + k时,从索引arr[0]arr[j]的数组元素之和等于从arr[j + 1]arr[n – 1]的元素之和,即

.
如果不存在这样的k则打印-1
例子:

一个简单的方法是运行两个循环。对于每个元素,找出左右元素之和之间的差异。最后,返回两个和之间的最小差。
一种有效的方法:首先计算前缀总和并存储在数组pre[]中,其中pre[i]存储从arr[0]arr[i]的数组元素的总和。对于每个索引,如果左侧元素的总和(包括元素本身,即 pre[i])小于或等于右侧元素的总和(pre[n – 1] – pre[i]),则更新k的值为min(k, (pre[n – 1] – pre[i]) – pre[i])
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the minimum value k to be added
int FindMinNum(int arr[], int n)
{
 
    // Array to store prefix sum
    int pre[n];
 
    // Initialize the prefix value for first index
    // as the first element of the array
    pre[0] = arr[0];
 
    // Compute the prefix sum for rest of the indices
    for (int i = 1; i < n; i++)
        pre[i] = pre[i - 1] + arr[i];
 
    int k = INT_MAX;
 
    for (int i = 0; i < n - 1; i++) {
 
        // Sum of elements from arr[i + 1] to arr[n - 1]
        int rightSum = pre[n - 1] - pre[i];
 
        // If sum on the right side of the ith element
        // is greater than or equal to the sum on the
        // left side then update the value of k
        if (rightSum >= pre[i])
            k = min(k, rightSum - pre[i]);
    }
 
    if (k != INT_MAX)
        return k;
 
    return -1;
}
 
// Driver code
int main()
{
    int arr[] = { 6, 7, 1, 3, 8, 2, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << FindMinNum(arr, n);
    return 0;
}


Java
// Java implementation of the approach
class GfG
{
 
// Function to return the minimum value k to be added
static int FindMinNum(int arr[], int n)
{
 
    // Array to store prefix sum
    int pre[] = new int[n];
 
    // Initialize the prefix value for first index
    // as the first element of the array
    pre[0] = arr[0];
 
    // Compute the prefix sum for rest of the indices
    for (int i = 1; i < n; i++)
        pre[i] = pre[i - 1] + arr[i];
 
    int k = Integer.MAX_VALUE;
 
    for (int i = 0; i < n - 1; i++)
    {
 
        // Sum of elements from arr[i + 1] to arr[n - 1]
        int rightSum = pre[n - 1] - pre[i];
 
        // If sum on the right side of the ith element
        // is greater than or equal to the sum on the
        // left side then update the value of k
        if (rightSum >= pre[i])
            k = Math.min(k, rightSum - pre[i]);
    }
 
    if (k != Integer.MAX_VALUE)
        return k;
 
    return -1;
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 6, 7, 1, 3, 8, 2, 4 };
    int n = arr.length;
    System.out.println(FindMinNum(arr, n));
}
}
 
// This code is contributed by Prerna Saini


Python3
# Python 3 implementation of the approach
import sys
 
# Function to return the minimum
# value k to be added
def FindMinNum(arr, n):
     
    # Array to store prefix sum
    pre = [0 for i in range(n)]
 
    # Initialize the prefix value for first
    # index as the first element of the array
    pre[0] = arr[0]
 
    # Compute the prefix sum for rest
    # of the indices
    for i in range(1, n, 1):
        pre[i] = pre[i - 1] + arr[i]
 
    k = sys.maxsize
 
    for i in range(n - 1):
         
        # Sum of elements from arr[i + 1] to arr[n - 1]
        rightSum = pre[n - 1] - pre[i]
 
        # If sum on the right side of the ith element
        # is greater than or equal to the sum on the
        # left side then update the value of k
        if (rightSum >= pre[i]):
            k = min(k, rightSum - pre[i])
 
    if (k != sys.maxsize):
        return k
 
    return -1
 
# Driver code
if __name__ == '__main__':
    arr = [6, 7, 1, 3, 8, 2, 4]
    n = len(arr)
    print(FindMinNum(arr, n))
 
# This code is contributed by
# Surendra_Gangwar


C#
// C# implementation of the approach
using System;
 
class GfG
{
 
    // Function to return the minimum value k to be added
    static int FindMinNum(int []arr, int n)
    {
     
        // Array to store prefix sum
        int []pre = new int[n];
     
        // Initialize the prefix value for first index
        // as the first element of the array
        pre[0] = arr[0];
     
        // Compute the prefix sum for rest of the indices
        for (int i = 1; i < n; i++)
            pre[i] = pre[i - 1] + arr[i];
     
        int k = int.MaxValue;
     
        for (int i = 0; i < n - 1; i++)
        {
     
            // Sum of elements from arr[i + 1] to arr[n - 1]
            int rightSum = pre[n - 1] - pre[i];
     
            // If sum on the right side of the ith element
            // is greater than or equal to the sum on the
            // left side then update the value of k
            if (rightSum >= pre[i])
                k = Math.Min(k, rightSum - pre[i]);
        }
     
        if (k != int.MaxValue)
            return k;
     
        return -1;
    }
     
    // Driver code
    public static void Main()
    {
        int []arr = { 6, 7, 1, 3, 8, 2, 4 };
        int n = arr.Length;
         
        Console.WriteLine(FindMinNum(arr, n));
    }
}
 
// This code is contributed by Ryuga


PHP
= $pre[$i])
            $k = min($k, $rightSum - $pre[$i]);
    }
 
    if ($k != PHP_INT_MAX)
        return $k;
 
    return -1;
}
 
// Driver code
$arr = array(6, 7, 1, 3, 8, 2, 4);
$n = sizeof($arr);
echo FindMinNum($arr, $n);
 
// This code is contributed by Akanksha Rai
?>


Javascript


输出:
3

时间复杂度: O(n)
辅助空间: O(n)
进一步优化:我们可以通过以下步骤避免使用额外的空间。
1) 计算所有元素的总和。
2) 不断加左和,总和减去左和就可以得到右和。
这个想法类似于平衡指数问题的优化解决方案。
时间复杂度: O(n)
辅助空间: O(1)