总和大于等于零的最长子数组
给定一个包含 N 个整数的数组。任务是找到最大长度子数组,使得其所有元素的总和大于或等于 0。
例子:
Input: arr[]= {-1, 4, -2, -5, 6, -8}
Output: 5
Explanation: {-1, 4, -2, -5, 6} forms the longest subarray with sum=2.
Input: arr[]={-5, -6}
Output: 0
Explanation: No such subarray is possible
一种朴素的方法是预先计算数组的前缀和。然后对每个开始和结束索引使用两个嵌套循环,如果直到结束索引的前缀和减去开始索引之前的前缀和大于等于 0,则相应地更新答案。
时间复杂度:O(N 2 )
一种有效的方法是使用二分搜索来解决以下问题。以下是解决上述问题的步骤:
- 首先,计算数组每个索引的后缀和并将其存储在另一个数组中。
- 使用另一个数组搜索空间来存储每个子数组的起点。
- 从第 0 个索引开始迭代,如果直到第 i 个索引的后缀大于搜索空间中最顶部的元素,则将该后缀总和添加到搜索空间。
- 使用二分搜索查找搜索空间中的最低索引,使得直到该索引的后缀总和减去直到 (i+1)'th 的后缀总和大于等于 0。如果存在任何此类索引,则相应地更新答案.
这里的关键观察是,如果后缀总和大于搜索空间中的所有其他后缀总和,则将后缀总和添加到搜索空间,因为必须最大化长度。
下面是上述方法的实现。
C++
// C++ Program to compute the
// longest subarray with
// sum greater than equal to 0.
#include
using namespace std;
// Function for the searching the
// starting index of the subarray
int search(int* searchspace, int s, int e, int key)
{
// -1 signifies that no
// starting point of the subarray
// is not found with sum greater
// than equal to 0.
int ans = -1;
// Binary search
while (s <= e) {
int mid = (s + e) / 2;
if (searchspace[mid] - key >= 0) {
ans = mid;
e = mid - 1;
}
else {
s = mid + 1;
}
}
return ans;
}
// Function to return the longest subarray
int longestSubarray(int a[], int n)
{
// Array for the suffix sum
// of the above the array.
int SuffixSum[n + 1];
SuffixSum[n] = 0;
for (int i = n - 1; i >= 0; --i) {
SuffixSum[i] = SuffixSum[i + 1] + a[i];
}
int ans = 0;
// Search Space for potential starting
// points of the subarray.
// It will store the suffix sum
// till i'th index in increasing order.
int searchspace[n];
// It will store the indexes
// till which the suffix sum
// is present in search space.
int index[n];
int j = 0;
for (int i = 0; i < n; ++i) {
// add the element to the search space if the j=0
// or if the topmost element is lesser
// than present suffix sum.
if (j == 0 or SuffixSum[i] > searchspace[j - 1]) {
searchspace[j] = SuffixSum[i];
index[j] = i;
j++;
}
int idx = search(searchspace, 0, j - 1, SuffixSum[i + 1]);
// Only when idx is not -1 an subarray is
// possible with ending index at i.
if (idx != -1)
ans = max(ans, i - index[idx] + 1);
}
return ans;
}
// Driver Code
int main()
{
int a[] = { -1, 4, -2, -5, 6, -8 };
int n = sizeof(a) / sizeof(a[0]);
cout << longestSubarray(a, n);
return 0;
}
Java
// Java Program to compute the
// longest subarray with
// sum greater than equal to 0.
import java.io.*;
class GFG {
// Function for the searching the
// starting index of the subarray
static int search(int searchspace[], int s, int e, int key)
{
// -1 signifies that no
// starting point of the subarray
// is not found with sum greater
// than equal to 0.
int ans = -1;
// Binary search
while (s <= e) {
int mid = (s + e) / 2;
if (searchspace[mid] - key >= 0) {
ans = mid;
e = mid - 1;
}
else {
s = mid + 1;
}
}
return ans;
}
// Function to return the longest subarray
static int longestSubarray(int []a, int n)
{
// Array for the suffix sum
// of the above the array.
int SuffixSum[] = new int[n+1];
SuffixSum[n] = 0;
for (int i = n - 1; i >= 0; --i) {
SuffixSum[i] = SuffixSum[i + 1] + a[i];
}
int ans = 0;
// Search Space for potential starting
// points of the subarray.
// It will store the suffix sum
// till i'th index in increasing order.
int searchspace[] = new int[n];
// It will store the indexes
// till which the suffix sum
// is present in search space.
int index[] = new int[n];
int j = 0;
for (int i = 0; i < n; ++i) {
// add the element to the search space if the j=0
// or if the topmost element is lesser
// than present suffix sum.
if ((j == 0) || SuffixSum[i] > searchspace[j - 1]) {
searchspace[j] = SuffixSum[i];
index[j] = i;
j++;
}
int idx = search(searchspace, 0, j - 1, SuffixSum[i + 1]);
// Only when idx is not -1 an subarray is
// possible with ending index at i.
if (idx != -1)
ans = Math.max(ans, i - index[idx] + 1);
}
return ans;
}
// Driver Code
public static void main (String[] args) {
int []a = { -1, 4, -2, -5, 6, -8 };
int n = a.length;
System.out.println(longestSubarray(a, n));
}
}
// This code is contributed
// by anuj_67..
Python3
# Python3 program to compute the longest
# with sum greater than equal to 0
import math as mt
# function for the searching the
# starting index of the subarray
def search(searchspace, s, e, key):
# -1 signifies that no starting point
# of the subarray is not found with
# sum greater than equal to 0.
ans = -1
# Binary search
while s <= e:
mid = (s + e) // 2
if searchspace[mid] - key >= 0:
ans = mid
e = mid - 1
else:
s = mid + 1
return ans
# function to return the longest subarray
def longestSubarray(a, n):
# Array for the suffix sum of
# the above the array
SuffixSum = [0 for i in range(n + 1)]
for i in range(n - 1, -1, -1):
SuffixSum[i] = SuffixSum[i + 1] + a[i]
ans = 0
# Search Space for potential starting
# points of the subarray.
# It will store the suffix sum
# till i'th index in increasing order
searchspace = [0 for i in range(n)]
# It will store the indexes
# till which the suffix sum
# is present in search space
index = [0 for i in range(n)]
j = 0
for i in range(n):
# add the element to the search space
# if the j=0 or if the topmost element
# is lesser than present suffix sum
if j == 0 or (SuffixSum[i] >
searchspace[j - 1]):
searchspace[j] = SuffixSum[i]
index[j] = i
j += 1
idx = search(searchspace, 0, j - 1,
SuffixSum[i + 1])
# Only when idx is not -1 an subarray is
# possible with ending index at i.
if idx != -1:
ans = max(ans, i - index[idx] + 1)
return ans
# Driver Code
a = [-1, 4, -2, -5, 6, -8]
n = len(a)
print(longestSubarray(a, n))
# This code is contributed
# by Mohit kumar 29
C#
// C# Program to compute the
// longest subarray with
// sum greater than equal to 0.
using System;
class GFG {
// Function for the searching the
// starting index of the subarray
static int search(int[] searchspace, int s, int e, int key)
{
// -1 signifies that no
// starting point of the subarray
// is not found with sum greater
// than equal to 0.
int ans = -1;
// Binary search
while (s <= e) {
int mid = (s + e) / 2;
if (searchspace[mid] - key >= 0) {
ans = mid;
e = mid - 1;
}
else {
s = mid + 1;
}
}
return ans;
}
// Function to return the longest subarray
static int longestSubarray(int[] a, int n)
{
// Array for the suffix sum
// of the above the array.
int[] SuffixSum = new int[n+1];
SuffixSum[n] = 0;
for (int i = n - 1; i >= 0; --i) {
SuffixSum[i] = SuffixSum[i + 1] + a[i];
}
int ans = 0;
// Search Space for potential starting
// points of the subarray.
// It will store the suffix sum
// till i'th index in increasing order.
int[] searchspace = new int[n];
// It will store the indexes
// till which the suffix sum
// is present in search space.
int[] index = new int[n];
int j = 0;
for (int i = 0; i < n; ++i) {
// add the element to the search space if the j=0
// or if the topmost element is lesser
// than present suffix sum.
if ((j == 0) || SuffixSum[i] > searchspace[j - 1]) {
searchspace[j] = SuffixSum[i];
index[j] = i;
j++;
}
int idx = search(searchspace, 0, j - 1, SuffixSum[i + 1]);
// Only when idx is not -1 an subarray is
// possible with ending index at i.
if (idx != -1)
ans = Math.Max(ans, i - index[idx] + 1);
}
return ans;
}
// Driver Code
public static void Main () {
int[] a = { -1, 4, -2, -5, 6, -8 };
int n = a.Length;
Console.Write(longestSubarray(a, n));
}
}
PHP
= 0)
{
$ans = $mid;
$e = $mid - 1;
}
else
{
$s = $mid + 1;
}
}
return $ans;
}
// Function to return the
// longest subarray
function longestSubarray(&$a, $n)
{
// Array for the suffix sum
// of the above the array.
$SuffixSum[$n] = 0;
for ($i = $n - 1; $i >= 0; --$i)
{
$SuffixSum[$i] = $SuffixSum[$i + 1] +
$a[$i];
}
$ans = 0;
// Search Space for potential
// starting points of the subarray.
// It will store the suffix sum
// till i'th index in increasing order.
// It will store the indexes
// till which the suffix sum
// is present in search space.
$j = 0;
for ($i = 0; $i < $n; ++$i)
{
// add the element to the search
// space if the j=0 or if the
// topmost element is lesser
// than present suffix sum.
if ($j == 0 or $SuffixSum[$i] >
$searchspace[$j - 1])
{
$searchspace[$j] = $SuffixSum[$i];
$index[$j] = $i;
$j++;
}
$idx = search($searchspace, 0, $j - 1,
$SuffixSum[$i + 1]);
// Only when idx is not -1 an
// subarray is possible with
// ending index at i.
if ($idx != -1)
$ans = max($ans, $i -
$index[$idx] + 1);
}
return $ans;
}
// Driver Code
$a = array(-1, 4, -2, -5, 6, -8 );
$n = sizeof($a);
echo (longestSubarray($a, $n));
// This code is contributed
// by Shivi_Aggarwal
?>
Javascript
输出:
5
时间复杂度: O(N * log N)
辅助空间: O(N)