给定一个由N个整数和一个整数K组成的数组A [] ,任务是找到总和大于或等于K的最小子数组的长度。如果不存在这样的子数组,则打印-1 。
例子:
Input: A[] = {2, -1, 2}, K = 3
Output: 3
Explanation:
Sum of the given array is 3.
Hence, the smallest possible subarray satisfying the required condition is the entire array.
Therefore, the length is 3.
Input: A[] = {2, 1, 1, -4, 3, 1, -1, 2}, K = 5
Output: 4
天真的方法:
解决该问题的最简单方法是生成给定数组的所有可能的子数组,并检查哪个子数组总和大于或等于K。在满足条件的所有此类子阵列中,打印具有最小长度的子阵列。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:
可以使用前缀和数组和二进制搜索来进一步优化上述方法。请按照以下步骤操作:
- 初始化数组以存储原始数组的Prefix和。
- 使用Map将前缀和数组与索引哈希在一起。
- 如果已经找到一个较大的和一个较小的索引,那么就没有必要对一个小于现在为止获得的最大前缀和的前缀和进行哈希处理。因此,哈希前缀和的增加顺序。
- 遍历数组,如果有任何元素大于或等于K ,则返回1作为答案。
- 否则,对于每个元素,对前缀和数组中的索引(i,n-1)执行二进制搜索,以找到总和至少为K的第一个索引。
- 返回从上述步骤获得的最小长度子数组。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to perform Binary Search
// and return the smallest index with
// sum greater than value
int binary_search(map >& m,
int value, int index)
{
// Search the value in map
auto it = m.lower_bound(value);
// If all keys in the map
// are less then value
if (it == m.end())
return 0;
// Check if the sum is found
// at a greater index
auto it1
= lower_bound(it->second.begin(),
it->second.end(), index);
if ((it1 - it->second.begin())
!= it->second.size())
return *it1;
return 0;
}
// Function to find the smallest subarray
// with sum greater than equal to K
int findSubarray(int arr[], int n, int k)
{
// Prefix sum array
int pre_array[n];
// Stores the hashes to prefix sum
map > m;
pre_array[0] = arr[0];
m[pre_array[0]].push_back(0);
// If any array element is
// greater than equal to k
if (arr[0] >= k)
return 1;
int ans = INT_MAX;
for (int i = 1; i < n; i++) {
pre_array[i]
= arr[i] + pre_array[i - 1];
// If prefix sum exceeds K
if (pre_array[i] >= k)
// Update size of subarray
ans = min(ans, i + 1);
auto it = m.rbegin();
// Hash prefix sum in
// increasing order
if (pre_array[i] >= it->first)
m[pre_array[i]].push_back(i);
}
for (int i = 1; i < n; i++) {
int temp
= binary_search(m,
pre_array[i - 1] + k,
i);
if (temp == 0)
continue;
// Update size of subarray
ans = min(ans, temp - i + 1);
}
// If any subarray is found
if (ans <= n)
return ans;
// If no such subarray exists
return -1;
}
// Driver Code
int main()
{
int arr[] = { 2, 1, 1, -4, 3, 1, -1, 2 };
int k = 5;
int n = sizeof(arr) / sizeof(arr[0]);
cout << findSubarray(arr, n, k) << endl;
return 0;
}
输出:
4
时间复杂度: O(NlogN)
辅助空间: O(N)