📌  相关文章
📜  来自给定数组的第一个总和为负的子数组

📅  最后修改于: 2021-10-27 08:45:54             🧑  作者: Mango

给定一个由N 个整数组成的数组 arr[] ,任务是找到第一个带有负和的子数组的开始和结束索引。如果不存在这样的子数组,则打印“-1”。

注意:在给定数组中有多个负和子数组的情况下,第一个子数组是指起始索引最低的子数组。

例子:

朴素的方法:朴素的方法是在数组中从左到右生成所有子数组,并检查这些子数组中是否有任何一个具有负和。如果是,则打印该子数组的开始和结束索引。

时间复杂度: O(N 2 )
辅助空间: O(1)

高效的方法:这个想法是使用前缀和和哈希来解决问题。以下是步骤:

  1. 计算数组的 Prefix Sum并将其存储到HashMap 中
  2. 遍历数组,对于每个i 个索引,其中 i 的范围是[0, N – 1] ,检查第i 个索引处的元素是否为负。如果是,则 arr[i] 是所需的子数组。
  3. 否则,查找从 i + 1 开始的索引,其中前缀和小于前缀和直到i
  4. 如果在上述步骤中找到任何此类索引,则来自索引 {i, index}的子数组给出第一个负子数组。
  5. 如果找不到这样的子数组,则打印“-1” 。否则,打印获得的子数组。

下面是上述方法的实现:

C++
// CPP program for the above approach
#include 
using namespace std;
  
// Function to check if a sum less
// than pre_sum is present
int b_search(int pre_sum,
             map >& m,
             int index)
{
    // Returns an iterator either equal
    // to given key or next greater
    auto it = m.lower_bound(pre_sum);
  
    if (it == m.begin())
        return -1;
  
    // Decrement the iterator
    it--;
  
    // Check if the sum found at
    // a greater index
    auto it1
        = lower_bound(it->second.begin(),
                      it->second.end(),
                      index);
  
    if (*it1 > index)
        return *it1;
  
    return -1;
}
  
// Function to return the index
// of first negative subarray sum
vector findSubarray(int arr[], int n)
{
    // Stores the prefix sum- index
    // mappings
    map > m;
  
    int sum = 0;
  
    // Stores the prefix sum of
    // the original array
    int prefix_sum[n];
  
    for (int i = 0; i < n; i++) {
        sum += arr[i];
  
        // Check if we get sum negative
        // starting from first element
        if (sum < 0)
            return { 0, i };
  
        prefix_sum[i] = sum;
        m[sum].push_back(i);
    }
  
    // Iterate through array find
    // the sum which is just less
    // then the previous prefix sum
    for (int i = 1; i < n; i++) {
  
        // Check if the starting element
        // is itself negative
        if (arr[i] < 0)
  
            // arr[i] becomes the required
            // subarray
            return { i, i };
  
        else {
            int pre_sum = prefix_sum[i - 1];
  
            // Find the index which forms
            // negative sum subarray
            // from i-th index
            int index = b_search(pre_sum,
                                 m, i);
  
            // If a subarray is found
            // starting from i-th index
            if (index != -1)
                return { i, index };
        }
    }
  
    // Return -1 if no such
    // subarray is present
    return { -1 };
}
  
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 1, 2, -1, 3, -4, 3, -5 };
  
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Function Call
    vector res = findSubarray(arr, n);
  
    // If subarray does not exist
    if (res[0] == -1)
        cout << "-1" << endl;
  
    // If the subarray exists
    else {
        cout << res[0]
             << " " << res[1];
    }
    return 0;
}


输出:
0 6

时间复杂度: O(N * log N)
辅助空间: O(N)