找到给定总和的子数组 |第 1 组(非负数)
给定一个非负整数的未排序数组arr和一个整数sum ,找到一个与给定总和相加的连续子数组。可能有多个子数组以 sum 作为给定的总和,首先打印这样的子数组。
例子 :
Input: arr[] = {1, 4, 20, 3, 10, 5}, sum = 33
Output: Sum found between indexes 2 and 4
Sum of elements between indices 2 and 4 is 20 + 3 + 10 = 33
Input: arr[] = {1, 4, 0, 0, 3, 10, 5}, sum = 7
Output: Sum found between indexes 1 and 4
Sum of elements between indices 1 and 4 is 4 + 0 + 0 + 3 = 7
Input: arr[] = {1, 4}, sum = 0
Output: No subarray found
There is no subarray with 0 sum
简单方法:一个简单的解决方案是逐个考虑所有子数组并检查每个子数组的总和。以下程序实现了简单的解决方案。运行两个循环:外循环选择起点 I,内循环尝试从 i 开始的所有子数组。
算法:
- 从头到尾遍历数组。
- 从每个索引开始另一个从i到数组末尾的循环以获取从 i 开始的所有子数组,并保留一个变量 sum 来计算总和。
- 对于内部循环中的每个索引更新sum = sum + array[j]
- 如果总和等于给定的总和,则打印子数组。
C++
/* A simple program to print subarray
with sum as given sum */
#include
using namespace std;
/* Returns true if the there is a subarray
of arr[] with sum equal to 'sum' otherwise
returns false. Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
int curr_sum, i, j;
// Pick a starting point
for (i = 0; i < n; i++) {
curr_sum = arr[i];
// try all subarrays starting with 'i'
for (j = i + 1; j <= n; j++) {
if (curr_sum == sum) {
cout << "Sum found between indexes "
<< i << " and " << j - 1;
return 1;
}
if (curr_sum > sum || j == n)
break;
curr_sum = curr_sum + arr[j];
}
}
cout << "No subarray found";
return 0;
}
// Driver Code
int main()
{
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 23;
subArraySum(arr, n, sum);
return 0;
}
// This code is contributed
// by rathbhupendra
C
/* A simple program to print
subarray with sum as given sum */
#include
/* Returns true if the there is a subarray
of arr[] with a sum equal to 'sum'
otherwise returns false. Also, prints
the result */
int subArraySum(int arr[], int n, int sum)
{
int curr_sum, i, j;
// Pick a starting point
for (i = 0; i < n; i++) {
curr_sum = arr[i];
// try all subarrays starting with 'i'
for (j = i + 1; j <= n; j++) {
if (curr_sum == sum) {
printf(
"Sum found between indexes %d and %d",
i, j - 1);
return 1;
}
if (curr_sum > sum || j == n)
break;
curr_sum = curr_sum + arr[j];
}
}
printf("No subarray found");
return 0;
}
// Driver program to test above function
int main()
{
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 23;
subArraySum(arr, n, sum);
return 0;
}
Java
class SubarraySum {
/* Returns true if the there is a
subarray of arr[] with a sum equal to
'sum' otherwise returns false.
Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
int curr_sum, i, j;
// Pick a starting point
for (i = 0; i < n; i++) {
curr_sum = arr[i];
// try all subarrays starting with 'i'
for (j = i + 1; j <= n; j++) {
if (curr_sum == sum) {
int p = j - 1;
System.out.println(
"Sum found between indexes " + i
+ " and " + p);
return 1;
}
if (curr_sum > sum || j == n)
break;
curr_sum = curr_sum + arr[j];
}
}
System.out.println("No subarray found");
return 0;
}
public static void main(String[] args)
{
SubarraySum arraysum = new SubarraySum();
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = arr.length;
int sum = 23;
arraysum.subArraySum(arr, n, sum);
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# Returns true if the
# there is a subarray
# of arr[] with sum
# equal to 'sum'
# otherwise returns
# false. Also, prints
# the result
def subArraySum(arr, n, sum_):
# Pick a starting
# point
for i in range(n):
curr_sum = arr[i]
# try all subarrays
# starting with 'i'
j = i + 1
while j <= n:
if curr_sum == sum_:
print ("Sum found between")
print("indexes % d and % d"%( i, j-1))
return 1
if curr_sum > sum_ or j == n:
break
curr_sum = curr_sum + arr[j]
j += 1
print ("No subarray found")
return 0
# Driver program
arr = [15, 2, 4, 8, 9, 5, 10, 23]
n = len(arr)
sum_ = 23
subArraySum(arr, n, sum_)
# This code is Contributed by shreyanshi_arun.
C#
// C# code to Find subarray
// with given sum
using System;
class GFG {
// Returns true if the there is a
// subarray of arr[] with sum
// equal to 'sum' otherwise returns
// false. Also, prints the result
int subArraySum(int[] arr, int n,
int sum)
{
int curr_sum, i, j;
// Pick a starting point
for (i = 0; i < n; i++) {
curr_sum = arr[i];
// try all subarrays
// starting with 'i'
for (j = i + 1; j <= n; j++) {
if (curr_sum == sum) {
int p = j - 1;
Console.Write("Sum found between "
+ "indexes " + i + " and " + p);
return 1;
}
if (curr_sum > sum || j == n)
break;
curr_sum = curr_sum + arr[j];
}
}
Console.Write("No subarray found");
return 0;
}
// Driver Code
public static void Main()
{
GFG arraysum = new GFG();
int[] arr = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = arr.Length;
int sum = 23;
arraysum.subArraySum(arr, n, sum);
}
}
// This code has been contributed
// by nitin mittal
PHP
$sum || $j == $n)
break;
$curr_sum = $curr_sum + $arr[$j];
}
}
echo "No subarray found";
return 0;
}
// Driver Code
$arr= array(15, 2, 4, 8, 9, 5, 10, 23);
$n = sizeof($arr);
$sum = 23;
subArraySum($arr, $n, $sum);
return 0;
// This code is contributed by AJit
?>
Javascript
C++
/* An efficient program to print
subarray with sum as given sum */
#include
using namespace std;
/* Returns true if the there is a subarray of
arr[] with a sum equal to 'sum' otherwise
returns false. Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
/* Initialize curr_sum as value of
first element and starting point as 0 */
int curr_sum = arr[0], start = 0, i;
/* Add elements one by one to curr_sum and
if the curr_sum exceeds the sum,
then remove starting element */
for (i = 1; i <= n; i++) {
// If curr_sum exceeds the sum,
// then remove the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to sum,
// then return true
if (curr_sum == sum) {
cout << "Sum found between indexes "
<< start << " and " << i - 1;
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
// If we reach here, then no subarray
cout << "No subarray found";
return 0;
}
// Driver Code
int main()
{
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 23;
subArraySum(arr, n, sum);
return 0;
}
// This code is contributed by SHUBHAMSINGH10
C
/* An efficient program to print
subarray with sum as given sum */
#include
/* Returns true if the there is a
subarray of arr[] with a sum
equal to 'sum' otherwise returns
false. Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
/* Initialize curr_sum as
value of first element and
starting point as 0 */
int curr_sum = arr[0], start = 0, i;
/* Add elements one by one to
curr_sum and if the curr_sum
exceeds the sum, then remove
starting element */
for (i = 1; i <= n; i++) {
// If curr_sum exceeds the sum,
// then remove the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to sum,
// then return true
if (curr_sum == sum) {
printf(
"Sum found between indexes %d and %d",
start, i - 1);
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
// If we reach here, then no subarray
printf("No subarray found");
return 0;
}
// Driver program to test above function
int main()
{
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 23;
subArraySum(arr, n, sum);
return 0;
}
Java
class SubarraySum {
/* Returns true if the there is
a subarray of arr[] with sum equal to
'sum' otherwise returns false.
Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
int curr_sum = arr[0], start = 0, i;
// Pick a starting point
for (i = 1; i <= n; i++) {
// If curr_sum exceeds the sum,
// then remove the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to sum,
// then return true
if (curr_sum == sum) {
int p = i - 1;
System.out.println(
"Sum found between indexes " + start
+ " and " + p);
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
System.out.println("No subarray found");
return 0;
}
public static void main(String[] args)
{
SubarraySum arraysum = new SubarraySum();
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = arr.length;
int sum = 23;
arraysum.subArraySum(arr, n, sum);
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# An efficient program
# to print subarray
# with sum as given sum
# Returns true if the
# there is a subarray
# of arr[] with sum
# equal to 'sum'
# otherwise returns
# false. Also, prints
# the result.
def subArraySum(arr, n, sum_):
# Initialize curr_sum as
# value of first element
# and starting point as 0
curr_sum = arr[0]
start = 0
# Add elements one by
# one to curr_sum and
# if the curr_sum exceeds
# the sum, then remove
# starting element
i = 1
while i <= n:
# If curr_sum exceeds
# the sum, then remove
# the starting elements
while curr_sum > sum_ and start < i-1:
curr_sum = curr_sum - arr[start]
start += 1
# If curr_sum becomes
# equal to sum, then
# return true
if curr_sum == sum_:
print ("Sum found between indexes")
print ("% d and % d"%(start, i-1))
return 1
# Add this element
# to curr_sum
if i < n:
curr_sum = curr_sum + arr[i]
i += 1
# If we reach here,
# then no subarray
print ("No subarray found")
return 0
# Driver program
arr = [15, 2, 4, 8, 9, 5, 10, 23]
n = len(arr)
sum_ = 23
subArraySum(arr, n, sum_)
# This code is Contributed by shreyanshi_arun.
C#
// An efficient C# program to print
// subarray with sum as given sum
using System;
class GFG {
// Returns true if the
// there is a subarray of
// arr[] with sum equal to
// 'sum' otherwise returns false.
// Also, prints the result
int subArraySum(int[] arr, int n,
int sum)
{
int curr_sum = arr[0],
start = 0, i;
// Pick a starting point
for (i = 1; i <= n; i++) {
// If curr_sum exceeds
// the sum, then remove
// the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to
// sum, then return true
if (curr_sum == sum) {
int p = i - 1;
Console.WriteLine("Sum found between "
+ "indexes " + start + " and " + p);
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
Console.WriteLine("No subarray found");
return 0;
}
// Driver code
public static void Main()
{
GFG arraysum = new GFG();
int[] arr = new int[] { 15, 2, 4, 8,
9, 5, 10, 23 };
int n = arr.Length;
int sum = 23;
arraysum.subArraySum(arr, n, sum);
}
}
// This code has been contributed by KRV.
PHP
$sum and
$start < $i - 1)
{
$curr_sum = $curr_sum -
$arr[$start];
$start++;
}
// If curr_sum becomes equal
// to sum, then return true
if ($curr_sum == $sum)
{
echo "Sum found between indexes",
" ", $start, " ",
"and ", " ", $i - 1;
return 1;
}
// Add this element
// to curr_sum
if ($i < $n)
$curr_sum = $curr_sum + $arr[$i];
}
// If we reach here,
// then no subarray
echo "No subarray found";
return 0;
}
// Driver Code
$arr = array(15, 2, 4, 8,
9, 5, 10, 23);
$n = count($arr);
$sum = 23;
subArraySum($arr, $n, $sum);
// This code has been
// contributed by anuj_67.
?>
Javascript
Sum found between indexes 1 and 4
复杂性分析:
- 时间复杂度:最坏情况下为 O(n^2)。
嵌套循环用于遍历数组,因此时间复杂度为 O(n^2) - 空间复杂度: O(1)。
因为需要恒定的额外空间。
有效方法:如果数组的所有元素都是正数,则有一个想法。如果子数组的总和大于给定总和,则将元素添加到当前子数组的总和不可能是x (给定总和)。想法是对滑动窗口使用类似的方法。从一个空子数组开始,向子数组添加元素,直到总和小于x 。如果总和大于x ,则从当前子数组的开头删除元素。
算法:
- 创建三个变量, l=0,sum=0
- 从头到尾遍历数组。
- 通过添加当前元素来更新变量 sum, sum = sum + array[i]
- 如果总和大于给定总和,则将变量 sum 更新为sum = sum – array[l] ,并将 l 更新为 l++。
- 如果总和等于给定总和,则打印子数组并中断循环。
C++
/* An efficient program to print
subarray with sum as given sum */
#include
using namespace std;
/* Returns true if the there is a subarray of
arr[] with a sum equal to 'sum' otherwise
returns false. Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
/* Initialize curr_sum as value of
first element and starting point as 0 */
int curr_sum = arr[0], start = 0, i;
/* Add elements one by one to curr_sum and
if the curr_sum exceeds the sum,
then remove starting element */
for (i = 1; i <= n; i++) {
// If curr_sum exceeds the sum,
// then remove the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to sum,
// then return true
if (curr_sum == sum) {
cout << "Sum found between indexes "
<< start << " and " << i - 1;
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
// If we reach here, then no subarray
cout << "No subarray found";
return 0;
}
// Driver Code
int main()
{
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 23;
subArraySum(arr, n, sum);
return 0;
}
// This code is contributed by SHUBHAMSINGH10
C
/* An efficient program to print
subarray with sum as given sum */
#include
/* Returns true if the there is a
subarray of arr[] with a sum
equal to 'sum' otherwise returns
false. Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
/* Initialize curr_sum as
value of first element and
starting point as 0 */
int curr_sum = arr[0], start = 0, i;
/* Add elements one by one to
curr_sum and if the curr_sum
exceeds the sum, then remove
starting element */
for (i = 1; i <= n; i++) {
// If curr_sum exceeds the sum,
// then remove the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to sum,
// then return true
if (curr_sum == sum) {
printf(
"Sum found between indexes %d and %d",
start, i - 1);
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
// If we reach here, then no subarray
printf("No subarray found");
return 0;
}
// Driver program to test above function
int main()
{
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 23;
subArraySum(arr, n, sum);
return 0;
}
Java
class SubarraySum {
/* Returns true if the there is
a subarray of arr[] with sum equal to
'sum' otherwise returns false.
Also, prints the result */
int subArraySum(int arr[], int n, int sum)
{
int curr_sum = arr[0], start = 0, i;
// Pick a starting point
for (i = 1; i <= n; i++) {
// If curr_sum exceeds the sum,
// then remove the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to sum,
// then return true
if (curr_sum == sum) {
int p = i - 1;
System.out.println(
"Sum found between indexes " + start
+ " and " + p);
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
System.out.println("No subarray found");
return 0;
}
public static void main(String[] args)
{
SubarraySum arraysum = new SubarraySum();
int arr[] = { 15, 2, 4, 8, 9, 5, 10, 23 };
int n = arr.length;
int sum = 23;
arraysum.subArraySum(arr, n, sum);
}
}
// This code has been contributed by Mayank Jaiswal(mayank_24)
Python3
# An efficient program
# to print subarray
# with sum as given sum
# Returns true if the
# there is a subarray
# of arr[] with sum
# equal to 'sum'
# otherwise returns
# false. Also, prints
# the result.
def subArraySum(arr, n, sum_):
# Initialize curr_sum as
# value of first element
# and starting point as 0
curr_sum = arr[0]
start = 0
# Add elements one by
# one to curr_sum and
# if the curr_sum exceeds
# the sum, then remove
# starting element
i = 1
while i <= n:
# If curr_sum exceeds
# the sum, then remove
# the starting elements
while curr_sum > sum_ and start < i-1:
curr_sum = curr_sum - arr[start]
start += 1
# If curr_sum becomes
# equal to sum, then
# return true
if curr_sum == sum_:
print ("Sum found between indexes")
print ("% d and % d"%(start, i-1))
return 1
# Add this element
# to curr_sum
if i < n:
curr_sum = curr_sum + arr[i]
i += 1
# If we reach here,
# then no subarray
print ("No subarray found")
return 0
# Driver program
arr = [15, 2, 4, 8, 9, 5, 10, 23]
n = len(arr)
sum_ = 23
subArraySum(arr, n, sum_)
# This code is Contributed by shreyanshi_arun.
C#
// An efficient C# program to print
// subarray with sum as given sum
using System;
class GFG {
// Returns true if the
// there is a subarray of
// arr[] with sum equal to
// 'sum' otherwise returns false.
// Also, prints the result
int subArraySum(int[] arr, int n,
int sum)
{
int curr_sum = arr[0],
start = 0, i;
// Pick a starting point
for (i = 1; i <= n; i++) {
// If curr_sum exceeds
// the sum, then remove
// the starting elements
while (curr_sum > sum && start < i - 1) {
curr_sum = curr_sum - arr[start];
start++;
}
// If curr_sum becomes equal to
// sum, then return true
if (curr_sum == sum) {
int p = i - 1;
Console.WriteLine("Sum found between "
+ "indexes " + start + " and " + p);
return 1;
}
// Add this element to curr_sum
if (i < n)
curr_sum = curr_sum + arr[i];
}
Console.WriteLine("No subarray found");
return 0;
}
// Driver code
public static void Main()
{
GFG arraysum = new GFG();
int[] arr = new int[] { 15, 2, 4, 8,
9, 5, 10, 23 };
int n = arr.Length;
int sum = 23;
arraysum.subArraySum(arr, n, sum);
}
}
// This code has been contributed by KRV.
PHP
$sum and
$start < $i - 1)
{
$curr_sum = $curr_sum -
$arr[$start];
$start++;
}
// If curr_sum becomes equal
// to sum, then return true
if ($curr_sum == $sum)
{
echo "Sum found between indexes",
" ", $start, " ",
"and ", " ", $i - 1;
return 1;
}
// Add this element
// to curr_sum
if ($i < $n)
$curr_sum = $curr_sum + $arr[$i];
}
// If we reach here,
// then no subarray
echo "No subarray found";
return 0;
}
// Driver Code
$arr = array(15, 2, 4, 8,
9, 5, 10, 23);
$n = count($arr);
$sum = 23;
subArraySum($arr, $n, $sum);
// This code has been
// contributed by anuj_67.
?>
Javascript
Sum found between indexes 1 and 4
复杂性分析:
- 时间复杂度: O(n)。
- 数组只被遍历一次以将元素插入到窗口中。需要 O(N) 时间
- 再次遍历 Array 以从窗口中删除元素。它也需要 O(N) 时间。
- 所以总时间将是O(N) + O(N) = O(2*N),类似于O(N)
- 空间复杂度: O(1)。
因为需要恒定的额外空间。
上述解决方案不处理负数。我们可以使用散列来处理负数。见下文第 2 组。
- 找到给定总和的子数组 |第 2 组(处理负数)
- 查找具有给定总和的子数组,在常数空间中允许负数