给定一个由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 Sum Array 和 Binary search 进一步优化上述方法。请按照以下步骤操作:
- 初始化一个数组以存储原始数组的 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)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。