有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置,求每一种窗口状态下的最大值。(如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值)
第一行输入n和w,分别代表数组长度和窗口大小第二行输入n个整数,表示数组中的各个元素
输出一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值
8 3 4 3 5 4 3 3 6 7
5 5 5 4 6 7
例如,数组为[4,3,5,4,3,3,6,7],窗口大小为3时:
[4 3 5] 4 3 3 6 7 窗口中最大值为5
4 [3 5 4] 3 3 6 7 窗口中最大值为5
4 3 [5 4 3] 3 6 7 窗口中最大值为5
4 3 5 [4 3 3] 6 7 窗口中最大值为4
4 3 5 4 [3 3 6] 7 窗口中最大值为6
4 3 5 4 3 [3 6 7] 窗口中最大值为7
输出的结果为{5 5 5 4 6 7}
#include<bits/stdc++.h>
using namespace std;
deque<int> dq;
int main() {
int n, w;
cin >> n >> w;
vector<int> a(n);
for (int i=0; i<n; ++i) {
cin >> a[i];
}
for (int i=0; i<n; ++i) {
while (!dq.empty() && a[dq.back()] <= a[i]) {
dq.pop_back();
}
dq.push_back(i);
if (dq.front() == i - w) {
dq.pop_front();
}
if (i >= w-1) {
cout << a[dq.front()] << ' ';
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *prev;
struct node *next;
} Node;
Node *createNode(int val);
void addLast(int val);
void removeFirst();
// the head and tail of the double-ended queue
Node *pHead = NULL;
Node *pTail = NULL;
int main(void) {
int n, w;
scanf("%d%d", &n, &w);
int *arr = (int *) malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
scanf("%d", arr + i);
}
int l = 0, r = 0;
while (r < w) {
addLast(arr[r++]);
}
int index = 0;
int *res = (int *) malloc((n - w + 1) * sizeof(int));
for (;;) {
res[index++] = pHead->val;
if (arr[l++] == pHead->val)
removeFirst();
if (r == n)
break;
addLast(arr[r++]);
}
// print result
for (int i = 0; i < index; i++) {
printf("%d ", res[i]);
}
// release memory
while (pHead != NULL)
removeFirst();
free(arr);
free(res);
return 0;
}
Node *createNode(int val) {
Node *node = (Node *) malloc(sizeof(Node));
node->val = val;
node->prev = NULL;
node->next = NULL;
return node;
}
void addLast(int val) {
Node *pNode = NULL;
while (pHead != NULL && val > pTail->val) {
pNode = pTail;
if (pHead == pTail) {
pHead = NULL;
pTail = NULL;
} else {
pTail = pTail->prev;
pTail->next = NULL;
}
free(pNode);
}
pNode = createNode(val);
if (NULL == pHead) {
pHead = pNode;
pTail = pNode;
return;
}
pTail->next = pNode;
pNode->prev = pTail;
pTail = pNode;
}
void removeFirst() {
Node *pNode = pHead;
if (pHead == pTail) {
pHead = NULL;
pTail = NULL;
} else {
pHead->next->prev = NULL;
pHead = pHead->next;
}
free(pNode);
} if __name__ == '__main__':
n, m = map(int, input().strip().split(' '))
nums = list(map(int, input().strip().split(' ')))
container = []
result = []
for i in range(n):
# 确保队里的对应index的值是降序排列
while len(container) > 0 and nums[i] >= nums[container[-1]]:
container.pop(-1)
container.append(i)
# 确保队列里的数都在有效范围内
while (i - container[0]) >= m:
container.pop(0)
if i >= (m - 1):
# 取出第一个元素,默认就是最大的
result.append(nums[container[0]])
print(' '.join([str(ele) for ele in result]))
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, w;
cin>>n>>w;
int a[n];
for(int i=0;i<n;i++)
cin>>a[i];
deque<int> Q;
for(int i=0;i<n;i++){
while(!Q.empty() && a[Q.back()]<=a[i])
Q.pop_back();
Q.push_back(i);
if(Q.front()==i-w)
Q.pop_front();
if(i>=w-1)
cout<<a[Q.front()]<<' ';
}
return 0;
} #include<bits/stdc++.h>
using namespace std;
int main()
{
int n,w,h=0,t=-1;
cin>>n>>w;
vector<int>x(n),res(n,0);
for(int i=0;i<n;i++)
cin>>x[i];
for(int i=0;i<n;i++)
{
while(t>=0&&x[res[t]]<x[i])
t--;
t++;
res[t]=i;
if(i>=w-1&&i<n)
{
h=0;
while(res[h]<i-w+1)
h++;
cout<<x[res[h]]<<" ";
}
}
return 0;
} import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.LinkedList;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]), w = Integer.parseInt(params[1]);
params = br.readLine().split(" ");
int[] arr = new int[n];
for(int i = 0; i < n; i++) arr[i] = Integer.parseInt(params[i]);
LinkedList<Integer> qmax = new LinkedList<>();
int index = 0;
for(int i = 0; i < n; i++){
// 保证队头最大
while(!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[i]) qmax.pollLast();
qmax.addLast(i);
if(qmax.peekFirst() == i - w) qmax.pollFirst(); // 窗口大小达到,左边界出队
if(i >= w - 1) System.out.print(arr[qmax.peekFirst()] + " ");
}
}
} import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
public class Main{
// 双端队列始终维持一个前大后小的结构,随着窗口右移,队列前面的元素会失效
// 维护队列:如果队尾对应的元素小,弹出不要;如果队尾对应元素大,就把新的数组的下标加进来,继续维护前大后小的结构
public static int[] getMaxWindow(int[] arr, int w) {
if (arr == null || w < 1 || arr.length < w) {
return null;
}
LinkedList<Integer> qMax = new LinkedList<>();
int[] result = new int[arr.length - w + 1];
int index = 0;
for (int i = 0; i < arr.length; i++) {
// 如果队尾对应的元素比较小,就弹出队尾,直到队尾的位置所代表的值比当前值arr[i]大
while (!qMax.isEmpty() && arr[qMax.peekLast()] <= arr[i]) {
qMax.pollLast();
}
qMax.addLast(i);
// 检查队头下标是否过期,过期就把队头弹出
if (qMax.peekFirst() == i - w) {
qMax.pollFirst();
}
// 如果窗口出现了,就开始记录每个窗口的最大值
if (i >= w - 1) {
result[index++] = arr[qMax.peekFirst()];
}
}
return result;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n;
int w;
String line;
while ((line = br.readLine()) != null) {
n = Integer.parseInt(line.split(" ")[0]);
w = Integer.parseInt(line.split(" ")[1]);
int[] data = new int[n];
String[] inputHelp = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
data[i] = Integer.parseInt(inputHelp[i]);
}
int[] res = getMaxWindow(data,w);
StringBuilder sb = new StringBuilder();
for (int i : res){
sb.append(i).append(" ");
}
System.out.println(sb);
}
}
}
#include <bits/stdc++.h>
using namespace std;
// 单调递增的单调队列
deque<int> dq;
void push_min(int val){
while(!dq.empty() && dq.back() < val){
dq.pop_back();
}
dq.push_back(val);
}
void pop_min(int val){
if(!dq.empty() && dq.front() == val){
dq.pop_front();
}
}
int getMax(){
return dq.front();
}
int main()
{
int n, w;
cin >> n >> w;
vector<int> nums(n);
for(int i = 0; i < n; ++i) cin >> nums[i];
for(int i = 0; i < w; ++i){
push_min(nums[i]);
}
vector<int> result;
result.push_back(getMax());
for(int i = w; i < n; ++i){
push_min(nums[i]);
pop_min(nums[i - w]);
result.push_back(getMax());
}
for(auto &c : result){
cout << c << " ";
}
return 0;
} #include "bits/stdc++.h"
using namespace std;
int main()
{
int n;cin>>n;
int w;cin>>w;
vector<int> nums(n);
for(int i=0;i<n;i++)cin>>nums[i];
deque<int> que;
//int max_ret=nums[0];
for(int i=0;i<w;i++)
{
if(que.size()==0||que.back()>=nums[i]) que.push_back(nums[i]);
else {
while(!que.empty()&&que.back()<nums[i])que.pop_back();
que.push_back(nums[i]);
}
}
cout<<que.front()<<' ';
for(int i=w;i<n;i++)
{
if(que.size()==0||que.back()>=nums[i]) que.push_back(nums[i]);
else {
while(!que.empty()&&que.back()<nums[i])que.pop_back();
que.push_back(nums[i]);
}
if(que.front()==nums[i-w])que.pop_front();
cout<<que.front()<<' ';
}
return 0;
} import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int w = in.nextInt();
int[] nums = new int[n];
int i = 0;
while (in.hasNext()) {
nums[i++] = in.nextInt();
}
int[] res = new Main().maxWindow(nums, w);
for (int num : res) {
System.out.print(num + " ");
}
}
public int[] maxWindow(int[] nums, int w) {
int n = nums.length;
if (nums == null || n == 0 || w <= 1) return nums;
int size = n - w + 1;
int[] res = new int[size];
Deque<Integer> queue = new ArrayDeque<>();
for (int i = 0; i < n; i++) {
while (!queue.isEmpty() && nums[queue.peekLast()] <= nums[i]) {
queue.pollLast();
}
queue.offerLast(i);
if (queue.peekFirst() <= i - w) {
queue.pollFirst();
}
if (i + 1 >= w) {
res[i + 1 - w] = nums[queue.peekFirst()];
}
}
return res;
}
} let line=readline()
let wSize=parseInt(line.split(' ')[1])
line=readline()
var arr=line.split(' ').map(item=>parseInt(item))
var res=[]
if(arr.length<=wSize){
res.push(Math.max(...arr))
console.log(res.join(' '))
}
let left=0,right=0
let subarr=[]
while(right<arr.length){
if(left&&arr[left-1]==subarr[0]){
subarr.shift()
}
if(arr[right]>=subarr[0]){
subarr=[arr[right]]
}else{
while(subarr[subarr.length-1]<arr[right]){
subarr.pop()
}
subarr.push(arr[right])
}
right++
if(right>=wSize){res.push(subarr[0]),left++}
}
console.log(res.join(' ')) #include <deque>
#include <iostream>
#include <vector>
using namespace std;
vector<int> process(const vector<int> &v, int w){
deque<int> dq;
vector<int> ans;
for(int i = 0; i < v.size(); i++){
while(!dq.empty() && v[dq.back()] <= v[i]){
dq.pop_back();
}
dq.push_back(i);
if(i >= w && i - w == dq.front())
dq.pop_front();
if(i >= w - 1)
ans.push_back(v[dq.front()]);
}
return ans;
}
int main(void){
int n, w;
cin >> n >> w;
vector<int> v(n);
for(int i = 0; i < n; i++)
cin >> v[i];
vector<int> ans = process(v, w);
for(auto a : ans)
cout << a << " ";
cout << endl;
return 0;
}
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int n, w, a[N];
int hh, tt, q[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> w;
for (int i = 0; i < n; i ++ ) cin >> a[i];
//max
tt = -1;
for (int i = 0; i < n; i ++ ) {
if (hh <= tt && q[hh] < i - w + 1) hh ++;
for (; hh <= tt && a[i] > a[q[tt]];) tt --;
q[++ tt] = i;
if (i - w + 1 >= 0) cout << a[q[hh]] << ' ';
}
return 0;
} 使用双端队列来实现
/*
* @Description: 生成窗口最大值数组
* @Author:
* @Date: 2020-10-29 14:53:17
* @LastEditTime: 2020-10-29 15:05:07
* @LastEditors: Please set LastEditors
*/
#include<iostream>
#include<vector>
#include<deque>
using namespace std;
int main(){
int n, w;
cin >> n >> w;
vector<int> arr(n);
for(int i = 0;i < n;i++){
cin >> arr[i];
}
deque<int> dq;
for(int i = 0;i < n;i++){
// 保证双端队列是一个递减的序列, 队尾的表示的值小于等于当前遍历的值,则队尾弹出,循环判断。
while(!dq.empty() && arr[dq.back()] <= arr[i]){
dq.pop_back();
}
dq.push_back(i);
// 如果当前队头==i-w 表示当前队头已经过期,则弹出队头
if(dq.front() == i - w){
dq.pop_front();
}
// 求出当前队头的最大值
if(i >= w - 1){
cout << arr[dq.front()] << " ";
}
}
system("pause");
return 0;
}
import java.util.Queue;
import java.util.LinkedList;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main{
private Queue<Integer> queue;
public Main(){
this.queue = new LinkedList<Integer>();
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
Main m = new Main();
String[] s1 = bf.readLine().split(" ");
int forLength = Integer.valueOf(s1[0]);
int windowLength = Integer.valueOf(s1[1]);
int[] result = new int[forLength-windowLength+1];
String[] s2 = bf.readLine().split(" ");
int[] array = new int[forLength];
for(int i=0;i<forLength;i++){
array[i] = Integer.valueOf(s2[i]);
}
m.windows(array,result,windowLength);
String out = "";
for(int j = 0;j<forLength-windowLength+1;j++){
int value = m.queue.poll();
out = out + value+ " ";
}
System.out.println(out);
}
public void windows(int[] array,int[] result,int windowlength){
int max = array[0];
for(int i=0;i<array.length-windowlength+1;i++){
max = array[i];
for (int j=i;j<windowlength+i;j++){
max = max>array[j]?max:array[j];
}
this.queue.offer(max);
}
}
} #include<cstdio>
#include<iostream>
#include<deque>
#include<vector>
using namespace std;
int main(){
int n,w;
deque<int> dq;
vector<int> vec;
cin>>n>>w;
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
if(dq.size()==0)
dq.push_back(i);
else{
if(i-dq.front()>w-1){
dq.pop_front();
}
while(dq.size()!=0&&a[i]>a[dq.back()]){
dq.pop_back();
}
dq.push_back(i);
if(i>=w-1){
vec.push_back(a[dq.front()]);
}
}
}
for(auto i:vec){
cout<<i<<" ";
}
return 0;
} # 利用python中List 模拟 双端队列 N, w = list(map(int, input().split())) nums = list(map(int, input().split())) queue = [] res = [] for i in range(N): while len(queue)>0 and nums[i] > nums[queue[-1]]: queue.pop() queue.append(i) if queue[0] == i - w: queue.pop(0) if i >= w-1 and len(queue) > 0: res.append(nums[queue[0]]) result = '' for i in range(len(res)-1): result += str(res[i]) result += ' ' result += str(res[-1]) print(result)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int w = sc.nextInt();
int[] x = new int[n];
for (int i = 0; i < n; i++){
x[i] = sc.nextInt();
}
if (n == 0) {
System.out.print("");
return;
}
int[] res = getMax(x, w);
for (int i = 0; i < res.length; i++){
System.out.print(res[i] + " ");
}
}
private static int[] getMax(int[] x, int w){
int len = x.length;
if (w == 1) return x;
int[] arr = new int[len - w + 1];
int left = 0;
int right = left + w - 1;
if (right >= len - 1) {
arr[0] = maxValue(x, left, len - 1);
return arr;
}
int i = 0;
int index = maxValue(x, left, right);
int pre = left;
left++;
right++;
arr[i++] = x[index];
while (right <= len-1){
if (index == pre){
index = maxValue(x, left, right);
arr[i++] = x[index];
} else {
if (x[index] < x[right]){
index = right;
arr[i++] = x[right];
} else {
arr[i++] = x[index];
}
}
left++;
right++;
if (index < left && right <= len-1){
index = maxValue(x, left, right);
}
}
return arr;
}
private static int maxValue(int[] x, int left, int right){
if (left == right) return x[left];
int maxValue = x[left];
int index = left;
while (left <= right){
if (x[left] > maxValue){
maxValue = x[left];
index = left;
}
left++;
}
return index;
}
}