You can solve this in O(N log K) time where N is size of array.
First notice that if we solve problem for min, the solution for max is same, just multiply original array elements by -1.
So to solve this we need a data structure that supports: additions, deletions, finding k-th item in collection, then we can just loop over all needed intervals using sliding window, adding and deleting items when needed.
Actually there are lots of structures that can support all those operations in O(log N) time, you can use segment tree, min/max heaps, order statistic tree (a type of B-tree) and some others.
An order statistic tree is a binary search tree that supports two additional operations beyond insertion, lookup and deletion:
Select(i) — find the i'th smallest element stored in the tree.
Rank(x) – find the rank of element x in the tree, i.e. its index in the sorted list of elements of the tree.
Both are O(log n) when a self-balancing tree is used as the base data structure.
Sample code (C++ with g++ compiler which luckily has order statistic tree in the library)
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;
int main()
{
int n,k,L;
cin>>n>>k>>L;
vector<int>A(n+1);
for(int i=0; i<n; i++)cin>>A[i];
ordered_set S;
for(int i=0; i<k; i++)
S.insert({A[i],i});
for(int i=k; i<=n; i++)
{
cout<<S.find_by_order(L-1)->first<<" ";
S.erase(S.find({A[i-k],i-k}));
S.insert({A[i],i});
}
}