有一个整型数组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; } }