如何利用C++、C、Python求具有Sum k的子阵列

215 阅读2分钟

问题

给出一个大小为N的无排序数组 arr大小 为N,请找出一个连续的子数组,它的总和为给定的数字 k

蛮力方法

一个简单的方法是逐个检查所有子数,并计算每个子数的总和。下面的程序实现了基本的解决方案。运行两个循环:外循环选择一个起点 i,而内循环尝试所有以 i开始的子数 。

这种方法将花费O(N2)时间和O(1)辅助空间。

高效的方法

这个概念是将数组中每个前缀的元素之和存储在一个哈希图中,其中键是每个前缀的总和,索引是具有该总和的最新索引。所以,要看是否有一个总和等于 k的子数组 ,就看每个索引I,然后加到该索引上,并把它保存在哈希姆表中。比方说sum是 。如果哈希图中的一个前缀的总和等于 sum - k,那么就会发现具有指定总和的子阵列。算法的步骤是。

  1. 创建一个哈希图来保存键值对,即key=每个前缀的sum,value=其索引,并创建一个变量来记录当前的 sum
  2. 遍历这个数组。
  3. 更新每个条目的和,即 sum = sum + array[i]。
  4. 如果某个前缀的和等于 k,就显示它。
  5. 如果在hashmap中找到(sum-k),则显示提供sum的子数组。
  6. 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