问题
给出一个大小为N的无排序数组 arr大小 为N,请找出一个连续的子数组,它的总和为给定的数字 k。
蛮力方法
一个简单的方法是逐个检查所有子数,并计算每个子数的总和。下面的程序实现了基本的解决方案。运行两个循环:外循环选择一个起点 i,而内循环尝试所有以 i开始的子数 。
这种方法将花费O(N2)时间和O(1)辅助空间。
高效的方法
这个概念是将数组中每个前缀的元素之和存储在一个哈希图中,其中键是每个前缀的总和,索引是具有该总和的最新索引。所以,要看是否有一个总和等于 k的子数组 ,就看每个索引I,然后加到该索引上,并把它保存在哈希姆表中。比方说sum是 和。如果哈希图中的一个前缀的总和等于 sum - k,那么就会发现具有指定总和的子阵列。算法的步骤是。
- 创建一个哈希图来保存键值对,即key=每个前缀的sum,value=其索引,并创建一个变量来记录当前的 sum。
- 遍历这个数组。
- 更新每个条目的和,即 sum = sum + array[i]。
- 如果某个前缀的和等于 k,就显示它。
- 如果在hashmap中找到(sum-k),则显示提供sum的子数组。
- 将 sum 和当前索引作为键值对放入hashmap中。
C++编程
#include<bits/stdc++.h>
using namespace std;
void subArrayequalsK(int arr[], int n, int k)
{
unordered_map<int, int> mp;
// Maintains prefix sum of elements
int sum = 0;
for (int i = 0; i < n; i++)
{
// add current element to k
sum = sum + arr[i];
// if any prefix sum is equal to target k
if (sum == k)
{
cout << "Found b/w"
<< 0 << " and " << i << endl;
return;
}
// If sum - k already exists in mp
if (mp.find(sum - k) != mp.end())
{
cout << "Found b/w "
<< mp[sum - k] + 1
<< " to " << i << endl;
return;
}
mp[sum] = i;
}
}
int main(){
int a[5] = {1, 3, -4, 2, 5};
int n=sizeof(a)/sizeof(a[0]);
int k =4;
subArrayequalsK(a, n, k);
}
输出
Found b/w 0 and 1
C#编程
using System;
using System.Collections.Generic;
public class Solution
{
public static void subArrayequalsK(int[] arr, int n, int k)
{
int sum = 0;
int begin = 0;
int finish = -1;
Dictionary<int, int> mp = new Dictionary<int, int>();
for (int i = 0; i < n; i++)
{
sum = sum + arr[i];
//check if some prefix sum is equal to k
if (sum == k)
{
begin = 0;
finish = i;
break;
}
//if mp already has the sum, we already
// have subarray with the k
if (mp.ContainsKey(sum - k))
{
begin = mp[sum - k] + 1;
finish = i;
break;
}
mp[sum] = i;
}
Console.WriteLine("Found b/w " + begin + " to " + finish);
}
static void Main(string[] args){
int[] arr = {1, 2, 3, 4};
int k = 3;
int n = 4;
subArrayequalsK(arr, n, k);
}
}
输出
Found b/w 0 and 1
Python编程
def subArrayequalsK(arr, n, k):
mp = {}
sum = 0
for i in range(0,n):
# add current element to sum
sum = sum + arr[i]
# if prefix sum is equal to target
if sum == k:
print("Found b/w 1 and", i+1)
return
# If sum - sum already exists in map
if (sum - k) in mp:
print("Found b/w", \
mp[sum - k] + 1, "and", i+1)
return
mp[sum] = i+1
l = [1, 2, 3, 4]
n= len(l)
k = 3
subArrayequalsK(l, n, k)
输出
Found b/w 1 and 2