设置 1:滑动窗口最大值(所有大小为 k 的子数组的最大值)。
给定一个大小为N的数组arr和一个整数K ,任务是找到每个大小为K 的连续子数组的最大值。
例子:
Input: arr[] = {1, 2, 3, 1, 4, 5, 2, 3, 6}, K = 3
Output: 3 3 4 5 5 5 6
All contiguous subarrays of size k are
{1, 2, 3} => 3
{2, 3, 1} => 3
{3, 1, 4} => 4
{1, 4, 5} => 5
{4, 5, 2} => 5
{5, 2, 3} => 5
{2, 3, 6} => 6
Input: arr[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, K = 4
Output: 10 10 10 15 15 90 90
方法:为了以较小的空间复杂度解决这个问题,我们可以使用两个指针技术。
- 第一个变量指针遍历子数组,找到给定大小K的最大元素
- 第二个变量指针标记第一个变量指针的结束索引,即(i + K – 1)th index 。
- 当第一个变量指针到达第二个变量指针的索引时,该子数组的最大值已被计算并被打印出来。
- 重复该过程,直到第二个变量指针到达最后一个数组索引(即 array_size – 1) 。
下面是上述方法的实现:
C++
// C++ program to find the maximum for each
// and every contiguous subarray of size K
#include
using namespace std;
// Function to find the maximum for each
// and every contiguous subarray of size k
void printKMax(int a[], int n, int k)
{
// If k = 1, print all elements
if (k == 1) {
for (int i = 0; i < n; i += 1)
cout << a[i] << " ";
return;
}
// Using p and q as variable pointers
// where p iterates through the subarray
// and q marks end of the subarray.
int p = 0,
q = k - 1,
t = p,
max = a[k - 1];
// Iterating through subarray.
while (q <= n - 1) {
// Finding max
// from the subarray.
if (a[p] > max)
max = a[p];
p += 1;
// Printing max of subarray
// and shifting pointers
// to next index.
if (q == p && p != n) {
cout << max << " ";
q++;
p = ++t;
if (q < n)
max = a[q];
}
}
}
// Driver Code
int main()
{
int a[] = { 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 };
int n = sizeof(a) / sizeof(a[0]);
int K = 3;
printKMax(a, n, K);
return 0;
}
Java
// Java program to find the maximum for each
// and every contiguous subarray of size K
import java.util.*;
class GFG{
// Function to find the maximum for each
// and every contiguous subarray of size k
static void printKMax(int a[], int n, int k)
{
// If k = 1, print all elements
if (k == 1) {
for (int i = 0; i < n; i += 1)
System.out.print(a[i]+ " ");
return;
}
// Using p and q as variable pointers
// where p iterates through the subarray
// and q marks end of the subarray.
int p = 0,
q = k - 1,
t = p,
max = a[k - 1];
// Iterating through subarray.
while (q <= n - 1) {
// Finding max
// from the subarray.
if (a[p] > max)
max = a[p];
p += 1;
// Printing max of subarray
// and shifting pointers
// to next index.
if (q == p && p != n) {
System.out.print(max+ " ");
q++;
p = ++t;
if (q < n)
max = a[q];
}
}
}
// Driver Code
public static void main(String[] args)
{
int a[] = { 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 };
int n = a.length;
int K = 3;
printKMax(a, n, K);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to find the maximum for each
# and every contiguous subarray of size K
# Function to find the maximum for each
# and every contiguous subarray of size k
def printKMax(a, n, k):
# If k = 1, prall elements
if (k == 1):
for i in range(n):
print(a[i], end=" ");
return;
# Using p and q as variable pointers
# where p iterates through the subarray
# and q marks end of the subarray.
p = 0;
q = k - 1;
t = p;
max = a[k - 1];
# Iterating through subarray.
while (q <= n - 1):
# Finding max
# from the subarray.
if (a[p] > max):
max = a[p];
p += 1;
# Printing max of subarray
# and shifting pointers
# to next index.
if (q == p and p != n):
print(max, end=" ");
q += 1;
p = t + 1;
t = p;
if (q < n):
max = a[q];
# Driver Code
if __name__ == '__main__':
a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
n = len(a);
K = 3;
printKMax(a, n, K);
# This code is contributed by Princi Singh
C#
// C# program to find the maximum for each
// and every contiguous subarray of size K
using System;
class GFG{
// Function to find the maximum for each
// and every contiguous subarray of size k
static void printKMax(int []a, int n, int k)
{
// If k = 1, print all elements
if (k == 1) {
for (int i = 0; i < n; i += 1)
Console.Write(a[i]+ " ");
return;
}
// Using p and q as variable pointers
// where p iterates through the subarray
// and q marks end of the subarray.
int p = 0,
q = k - 1,
t = p,
max = a[k - 1];
// Iterating through subarray.
while (q <= n - 1) {
// Finding max
// from the subarray.
if (a[p] > max)
max = a[p];
p += 1;
// Printing max of subarray
// and shifting pointers
// to next index.
if (q == p && p != n) {
Console.Write(max+ " ");
q++;
p = ++t;
if (q < n)
max = a[q];
}
}
}
// Driver Code
public static void Main(String[] args)
{
int []a = { 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 };
int n = a.Length;
int K = 3;
printKMax(a, n, K);
}
}
// This code is contributed by Rajput-Ji
Javascript
C++
// C++ program to find the maximum for each
// and every contiguous subarray of size K
#include
using namespace std;
// Function to find the maximum for each
// and every contiguous subarray of size k
void printKMax(int a[], int n, int k)
{
// If k = 1, print all elements
if (k == 1) {
for (int i = 0; i < n; i += 1)
cout << a[i] << " ";
return;
}
//left[i] stores the maximum value to left of i in the current block
//right[i] stores the maximum value to the right of i in the current block
int left[n],right[n];
for(int i=0;i
输出
3 4 5 6 7 8 9 10
时间复杂度:O(N*k)
辅助空间复杂度:O(1)
方法 2:使用动态规划:
- 首先,将整个数组分成 k 个元素的块,使得每个块包含数组的 k 个元素(并不总是最后一个块)。
- 维护两个 dp 数组,即 left 和 right。
- left[i]是当前块(当前元素所在的块)中当前元素(包括当前元素)左侧的所有元素的最大值。
- 类似地, right[i]是当前块(当前元素所在的块)中当前元素(包括当前元素)右侧的所有元素的最大值。
- 最后,在计算任意长度为 k 的子数组中的最大元素时,我们计算 right[l] 和 left[r] 的最大值
其中l = 当前子数组的起始索引,r = 当前子数组的结束索引
下面是上述方法的实现,
C++
// C++ program to find the maximum for each
// and every contiguous subarray of size K
#include
using namespace std;
// Function to find the maximum for each
// and every contiguous subarray of size k
void printKMax(int a[], int n, int k)
{
// If k = 1, print all elements
if (k == 1) {
for (int i = 0; i < n; i += 1)
cout << a[i] << " ";
return;
}
//left[i] stores the maximum value to left of i in the current block
//right[i] stores the maximum value to the right of i in the current block
int left[n],right[n];
for(int i=0;i
输出
3 4 5 6 7 8 9 10
时间复杂度:O(n)
辅助空间:O(n)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live