📜  第 K 个最大和连续子阵列

📅  最后修改于: 2021-10-28 01:48:27             🧑  作者: Mango

给定一个整数数组。编写一个程序,找出具有负数和正数的数字数组中连续子数组的第 K 个最大和。

例子:

Input: a[] = {20, -5, -1} 
         k = 3
Output: 14
Explanation: All sum of contiguous 
subarrays are (20, 15, 14, -5, -6, -1) 
so the 3rd largest sum is 14.

Input: a[] = {10, -10, 20, -40} 
         k = 6
Output: -10 
Explanation: The 6th largest sum among 
sum of all contiguous subarrays is -10.

一种蛮力方法是将所有连续的和存储在另一个数组中并对其进行排序并打印第 k 大。但是在元素数量很大的情况下,我们存储连续和的数组将耗尽内存,因为连续子数组的数量将很大(二次顺序)

一种有效的方法是将数组的预和存储在 sum[] 数组中。我们可以找到从索引 i 到 j 的连续子数组的总和为 sum[j]-sum[i-1]

现在为了存储第 K 个最大的和,使用一个最小堆(优先级队列),我们将连续的和推入其中,直到我们获得 K 个元素,一旦我们有了 K 个元素,检查该元素是否大于它插入的第 K 个元素最小堆弹出最小堆中的顶部元素,否则不插入。最后,最小堆中的顶部元素将是您的答案。

下面是上述方法的实现。

C++
// CPP program to find the k-th largest sum
// of subarray
#include 
using namespace std;
 
// function to calculate kth largest element
// in contiguous subarray sum
int kthLargestSum(int arr[], int n, int k)
{
    // array to store predix sums
    int sum[n + 1];
    sum[0] = 0;
    sum[1] = arr[0];
    for (int i = 2; i <= n; i++)
        sum[i] = sum[i - 1] + arr[i - 1];
 
    // priority_queue of min heap
    priority_queue, greater > Q;
 
    // loop to calculate the contiguous subarray
    // sum position-wise
    for (int i = 1; i <= n; i++)
    {
 
        // loop to traverse all positions that
        // form contiguous subarray
        for (int j = i; j <= n; j++)
        {
            // calculates the contiguous subarray
            // sum from j to i index
            int x = sum[j] - sum[i - 1];
 
            // if queue has less then k elements,
            // then simply push it
            if (Q.size() < k)
                Q.push(x);
 
            else
            {
                // it the min heap has equal to
                // k elements then just check
                // if the largest kth element is
                // smaller than x then insert
                // else its of no use
                if (Q.top() < x)
                {
                    Q.pop();
                    Q.push(x);
                }
            }
        }
    }
 
    // the top element will be then kth
    // largest element
    return Q.top();
}
 
// Driver program to test above function
int main()
{
    int a[] = { 10, -10, 20, -40 };
    int n = sizeof(a) / sizeof(a[0]);
    int k = 6;
 
    // calls the function to find out the
    // k-th largest sum
    cout << kthLargestSum(a, n, k);
    return 0;
}


Java
// Java program to find the k-th
// argest sum of subarray
import java.util.*;
 
class KthLargestSumSubArray
{
    // function to calculate kth largest
    // element in contiguous subarray sum
    static int kthLargestSum(int arr[], int n, int k)
    {
        // array to store predix sums
        int sum[] = new int[n + 1];
        sum[0] = 0;
        sum[1] = arr[0];
        for (int i = 2; i <= n; i++)
            sum[i] = sum[i - 1] + arr[i - 1];
         
        // priority_queue of min heap
        PriorityQueue Q = new PriorityQueue ();
         
        // loop to calculate the contiguous subarray
        // sum position-wise
        for (int i = 1; i <= n; i++)
        {
     
            // loop to traverse all positions that
            // form contiguous subarray
            for (int j = i; j <= n; j++)
            {
                // calculates the contiguous subarray
                // sum from j to i index
                int x = sum[j] - sum[i - 1];
     
                // if queue has less then k elements,
                // then simply push it
                if (Q.size() < k)
                    Q.add(x);
     
                else
                {
                    // it the min heap has equal to
                    // k elements then just check
                    // if the largest kth element is
                    // smaller than x then insert
                    // else its of no use
                    if (Q.peek() < x)
                    {
                        Q.poll();
                        Q.add(x);
                    }
                }
            }
        }
         
        // the top element will be then kth
        // largest element
        return Q.poll();
    }
     
    // Driver Code
    public static void main(String[] args)
    {
        int a[] = new int[]{ 10, -10, 20, -40 };
        int n = a.length;
        int k = 6;
 
        // calls the function to find out the
        // k-th largest sum
        System.out.println(kthLargestSum(a, n, k));
    }
}
 
/* This code is contributed by Danish Kaleem */


Python3
# Python program to find the k-th largest sum
# of subarray
import heapq
 
# function to calculate kth largest element
# in contiguous subarray sum
def kthLargestSum(arr, n, k):
     
    # array to store predix sums
    sum = []
    sum.append(0)
    sum.append(arr[0])
    for i in range(2, n + 1):
        sum.append(sum[i - 1] + arr[i - 1])
         
    # priority_queue of min heap
    Q = []
    heapq.heapify(Q)
     
    # loop to calculate the contiguous subarray
    # sum position-wise
    for i in range(1, n + 1):
         
        # loop to traverse all positions that
        # form contiguous subarray
        for j in range(i, n + 1):
            x = sum[j] - sum[i - 1]
             
            # if queue has less then k elements,
            # then simply push it
            if len(Q) < k:
                heapq.heappush(Q, x)
            else:
                # it the min heap has equal to
                # k elements then just check
                # if the largest kth element is
                # smaller than x then insert
                # else its of no use
                if Q[0] < x:
                    heapq.heappop(Q)
                    heapq.heappush(Q, x)
     
    # the top element will be then kth
    # largest element
    return Q[0]
 
# Driver program to test above function
a = [10,-10,20,-40]
n = len(a)
k = 6
 
# calls the function to find out the
# k-th largest sum
print(kthLargestSum(a,n,k))
 
 
# This code is contributed by Kumar Suman


C#
// C# program to find the k-th
// argest sum of subarray
using System;
using System.Collections.Generic;
public class KthLargestSumSubArray
{
 
  // function to calculate kth largest
  // element in contiguous subarray sum
  static int kthLargestSum(int []arr, int n, int k)
  {
 
    // array to store predix sums
    int []sum = new int[n + 1];
    sum[0] = 0;
    sum[1] = arr[0];
    for (int i = 2; i <= n; i++)
      sum[i] = sum[i - 1] + arr[i - 1];
 
    // priority_queue of min heap
    List Q = new List ();
 
    // loop to calculate the contiguous subarray
    // sum position-wise
    for (int i = 1; i <= n; i++)
    {
 
      // loop to traverse all positions that
      // form contiguous subarray
      for (int j = i; j <= n; j++)
      {
        // calculates the contiguous subarray
        // sum from j to i index
        int x = sum[j] - sum[i - 1];
 
        // if queue has less then k elements,
        // then simply push it
        if (Q.Count < k)
          Q.Add(x);
 
        else
        {
          // it the min heap has equal to
          // k elements then just check
          // if the largest kth element is
          // smaller than x then insert
          // else its of no use
          Q.Sort();
          if (Q[0] < x)
          {
            Q.RemoveAt(0);
            Q.Add(x);
          }
        }
        Q.Sort();
      }
    }
 
    // the top element will be then kth
    // largest element
    return Q[0];
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int []a = new int[]{ 10, -10, 20, -40 };
    int n = a.Length;
    int k = 6;
 
    // calls the function to find out the
    // k-th largest sum
    Console.WriteLine(kthLargestSum(a, n, k));
  }
}
 
// This code contributed by Rajput-Ji


输出:

-10

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程