📜  查找具有最大峰值的长度为K的子数组

📅  最后修改于: 2021-04-21 22:06:06             🧑  作者: Mango

给定一个长度为n的数组arr []和一个正整数K ,我们必须找到一个长度为K的子数组,数组在其中具有最大的峰值。

段[l,r]的峰值是那些索引,使得l a [i-1] a [i + 1]

注意:段的边界索引l和r不是峰值。如果有许多具有最大峰值的子阵列,则打印该子阵列的最小左索引。

例子:

方法:

解决此问题的方法是使用滑动窗口,在该窗口中,我们跨过K大小的窗口滑动,并找到每个窗口中峰的总数,无论哪个窗口给出最大的峰数就是答案。在移动右索引时,我们检查添加的索引是否为峰值,增加计数,在移动左索引时,我们检查删除的索引是否为峰值(如果是峰值),然后减少计数。我们总是有一个大小为K的窗口。

下面是上述方法的实现:

C++
// C++ implementation to Find subarray
// of Length K with Maximum Peak
  
#include 
using namespace std;
  
// Function to find the subarray
void findSubArray(int* a, int n, int k)
{
    // Make prefix array to store
    // the prefix sum of peak count
    int pref[n];
  
    pref[0] = 0;
  
    for (int i = 1; i < n - 1; ++i) {
  
        // Count peak for previous index
        pref[i] = pref[i - 1];
  
        // Check if this element is a peak
        if (a[i] > a[i - 1] && a[i] > a[i + 1])
  
            // Increment the count
            pref[i]++;
    }
  
    int peak = 0, left = 0;
  
    for (int i = 0; i + k - 1 < n; ++i)
  
        // Check if number of peak in the sub array
        // whose l = i is greater or not
        if (pref[i + k - 2] - pref[i] > peak) {
            peak = pref[i + k - 2] - pref[i];
            left = i;
        }
  
    // Print the result
    cout << "Left = " << left + 1 << endl;
    cout << "Right = " << left + k << endl;
    cout << "Peak = " << peak << endl;
}
  
// Driver code
int main()
{
    int arr[] = { 3, 2, 3, 2, 1 };
  
    int n = sizeof(arr) / sizeof(arr[0]);
  
    int k = 3;
  
    findSubArray(arr, n, k);
  
    return 0;
}


Java
// Java implementation to Find subarray
// of Length K with Maximum Peak
  
class GFG{
   
// Function to find the subarray
static void findSubArray(int []a, int n, int k)
{
    // Make prefix array to store
    // the prefix sum of peak count
    int []pref = new int[n];
   
    pref[0] = 0;
   
    for (int i = 1; i < n - 1; ++i) {
   
        // Count peak for previous index
        pref[i] = pref[i - 1];
   
        // Check if this element is a peak
        if (a[i] > a[i - 1] && a[i] > a[i + 1])
   
            // Increment the count
            pref[i]++;
    }
   
    int peak = 0, left = 0;
   
    for (int i = 0; i + k - 1 < n; ++i)
   
        // Check if number of peak in the sub array
        // whose l = i is greater or not
        if (pref[i + k - 2] - pref[i] > peak) {
            peak = pref[i + k - 2] - pref[i];
            left = i;
        }
   
    // Print the result
    System.out.print("Left = " +  (left + 1) +"\n");
    System.out.print("Right = " +  (left + k) +"\n");
    System.out.print("Peak = " +  peak +"\n");
}
   
// Driver code
public static void main(String[] args)
{
    int arr[] = { 3, 2, 3, 2, 1 };
   
    int n = arr.length;
   
    int k = 3;
   
    findSubArray(arr, n, k);
   
}
}
  
// This code contributed by Princi Singh


Python3
# Python3 implementation to Find subarray
# of Length K with Maximum Peak
  
# Function to find the subarray
def findSubArray(a, n, k):
  
    # Make prefix array to store
    # the prefix sum of peak count
    pref = [0 for i in range(n)]
  
    pref[0] = 0
  
    for i in range(1, n - 1, 1):
        # Count peak for previous index
        pref[i] = pref[i - 1]
  
        # Check if this element is a peak
        if (a[i] > a[i - 1] and a[i] > a[i + 1]):
            # Increment the count
            pref[i] += 1
  
    peak = 0
    left = 0
  
    for i in range(0, n - k + 1, 1):
  
        # Check if number of peak in the sub array
        # whose l = i is greater or not
        if (pref[i + k - 2] - pref[i] > peak):
            peak = pref[i + k - 2] - pref[i]
            left = i
  
    # Print the result
    print("Left =",left + 1)
    print("Right =",left + k)
    print("Peak =",peak)
  
# Driver code
if __name__ == '__main__':
    arr = [3, 2, 3, 2, 1]
  
    n = len(arr)
    k = 3
    findSubArray(arr, n, k)
  
# This code is contributed by Surendra_Gangwar


C#
// C# implementation to Find subarray
// of Length K with Maximum Peak
using System;
  
class GFG{
  
// Function to find the subarray
static void findSubArray(int []a, int n, int k)
{
      
    // Make prefix array to store
    // the prefix sum of peak count
    int []pref = new int[n];
      
    pref[0] = 0;
  
    for(int i = 1; i < n - 1; ++i)
    {
          
       // Count peak for previous index
       pref[i] = pref[i - 1];
         
       // Check if this element is a peak
       if (a[i] > a[i - 1] && a[i] > a[i + 1])
       {
           // Increment the count
           pref[i]++;
       }
    }
  
    int peak = 0;
    int left = 0;
      
    for(int i = 0; i + k - 1 < n; ++i)
    {
          
       // Check if number of peak in the sub array
       // whose l = i is greater or not
       if (pref[i + k - 2] - pref[i] > peak)
       {
           peak = pref[i + k - 2] - pref[i];
           left = i;
       }
    }
         
    // Print the result
    Console.Write("Left = " + (left + 1) + "\n");
    Console.Write("Right = " + (left + k) + "\n");
    Console.Write("Peak = " + peak + "\n");
}
  
// Driver code
public static void Main(String[] args)
{
    int []arr = { 3, 2, 3, 2, 1 };
    int n = arr.Length;
    int k = 3;
  
    findSubArray(arr, n, k);
}
}
  
// This code is contributed by Rohit_ranjan


输出:
Left = 2
Right = 4
Peak = 1

时间复杂度: O(N)