给定一个包含整数的大小为N的数组arr[] 。任务是找到总和等于给定值K的最长子数组的长度。
例子:
Input: arr[] = {2, 3, 4, 2, 1, 1}, K = 10
Output: 4
Explanation:
The subarray {3, 4, 2, 1} gives summation as 10.
Input: arr[] = {6, 8, 14, 9, 4, 11, 10}, K = 13
Output: 2
Explanation:
The subarray {9, 4} gives summation as 13.
朴素的方法:请参考这篇文章。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效的方法:这个想法是使用二分搜索来找到总和为K的最大长度的子数组。以下是步骤:
- 从给定的数组arr[]创建一个前缀和数组(比如pref[] )。
- 对于前缀数组pref[]中的每个元素进行二分搜索:
- 将ans 、 start和end变量初始化为-1, 0 , 和N分别。
- 找到中间索引(比如mid )。
- 如果pref[mid] – val ≤ K则将起始变量更新为mid + 1并将ans 更新为mid 。
- 否则将 end 变量更新为mid – 1 。
- 从上述二分搜索中返回ans的值。
- 如果当前子数组长度小于(ans – i) ,则将最大长度更新为(ans – i) 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// To store the prefix sum array
vector v;
// Function for searching the
// lower bound of the subarray
int bin(int val, int k, int n)
{
int lo = 0;
int hi = n;
int mid;
int ans = -1;
// Iterate until low less
// than equal to high
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
// For each mid finding sum
// of sub array less than
// or equal to k
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
// Return the final answer
return ans;
}
// Function to find the length of
// subarray with sum K
void findSubarraySumK(int arr[], int N, int K)
{
// Initialize sum to 0
int sum = 0;
v.push_back(0);
// Push the prefix sum of the
// array arr[] in prefix[]
for (int i = 0; i < N; i++) {
sum += arr[i];
v.push_back(sum);
}
int l = 0, ans = 0, r;
for (int i = 0; i < N; i++) {
// Search r for each i
r = bin(v[i], K, N);
// Update ans
ans = max(ans, r - i);
}
// Print the length of subarray
// found in the array
cout << ans;
}
// Driver Code
int main()
{
// Given array arr[]
int arr[] = { 6, 8, 14, 9, 4, 11, 10 };
int N = sizeof(arr) / sizeof(arr[0]);
// Given sum K
int K = 13;
// Function Call
findSubarraySumK(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// To store the prefix sum array
static Vector v = new Vector();
// Function for searching the
// lower bound of the subarray
static int bin(int val, int k, int n)
{
int lo = 0;
int hi = n;
int mid;
int ans = -1;
// Iterate until low less
// than equal to high
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
// For each mid finding sum
// of sub array less than
// or equal to k
if (v.get(mid) - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
// Return the final answer
return ans;
}
// Function to find the length of
// subarray with sum K
static void findSubarraySumK(int arr[], int N, int K)
{
// Initialize sum to 0
int sum = 0;
v.add(0);
// Push the prefix sum of the
// array arr[] in prefix[]
for (int i = 0; i < N; i++) {
sum += arr[i];
v.add(sum);
}
int l = 0, ans = 0, r;
for (int i = 0; i < v.size(); i++) {
// Search r for each i
r = bin(v.get(i), K, N);
// Update ans
ans = Math.max(ans, r - i);
}
// Print the length of subarray
// found in the array
System.out.print(ans);
}
// Driver Code
public static void main(String[] args)
{
// Given array arr[]
int arr[] = { 6, 8, 14, 9, 4, 11, 10 };
int N = arr.length;
// Given sum K
int K = 13;
// Function call
findSubarraySumK(arr, N, K);
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program for the above approach
# To store the prefix sum1 array
v = []
# Function for searching the
# lower bound of the subarray
def bin1(val, k, n):
global v
lo = 0
hi = n
mid = 0
ans = -1
# Iterate until low less
# than equal to high
while (lo <= hi):
mid = lo + ((hi - lo) // 2)
# For each mid finding sum1
# of sub array less than
# or equal to k
if (v[mid] - val <= k):
lo = mid + 1
ans = mid
else:
hi = mid - 1
# Return the final answer
return ans
# Function to find the length of
# subarray with sum1 K
def findSubarraysum1K(arr, N, K):
global v
# Initialize sum1 to 0
sum1 = 0
v.append(0)
# Push the prefix sum1 of the
# array arr[] in prefix[]
for i in range(N):
sum1 += arr[i]
v.append(sum1)
l = 0
ans = 0
r = 0
for i in range(len(v)):
# Search r for each i
r = bin1(v[i], K, N)
# Update ans
ans = max(ans, r - i)
# Print the length of subarray
# found in the array
print(ans)
# Driver Code
if __name__ == '__main__':
# Given array arr[]
arr = [6, 8, 14, 9, 4, 11, 10]
N = len(arr)
# Given sum1 K
K = 13
# Function Call
findSubarraysum1K(arr, N, K)
# This code is contributed by ipg2016107
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// To store the prefix sum array
static List v = new List();
// Function for searching the
// lower bound of the subarray
static int bin(int val, int k, int n)
{
int lo = 0;
int hi = n;
int mid;
int ans = -1;
// Iterate until low less
// than equal to high
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
// For each mid finding sum
// of sub array less than
// or equal to k
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
// Return the final answer
return ans;
}
// Function to find the length of
// subarray with sum K
static void findSubarraySumK(int[] arr, int N, int K)
{
// Initialize sum to 0
int sum = 0;
v.Add(0);
// Push the prefix sum of the
// array []arr in prefix[]
for (int i = 0; i < N; i++) {
sum += arr[i];
v.Add(sum);
}
int ans = 0, r;
for (int i = 0; i < v.Count; i++) {
// Search r for each i
r = bin(v[i], K, N);
// Update ans
ans = Math.Max(ans, r - i);
}
// Print the length of subarray
// found in the array
Console.Write(ans);
}
// Driver Code
public static void Main(String[] args)
{
// Given array []arr
int[] arr = { 6, 8, 14, 9, 4, 11, 10 };
int N = arr.Length;
// Given sum K
int K = 13;
// Function call
findSubarraySumK(arr, N, K);
}
}
// This code is contributed by gauravrajput1
Javascript
输出
2
时间复杂度: O(N*log 2 N)
辅助空间: O(N)
高效方法:对于O(N) 方法,请参考本文的高效方法。