整数列表nums有一个大小为k的滑动窗口,它从列表的最左侧移动到列表的最右侧,滑动窗口每次只向右移动一位,请编写程序输出每次滑动窗口中的最大值所形成的的列表。 输入描述: 第一行:输入一个整数列表; 第二行:输入一个整数,表示滑动窗口的大小。 输出描述: 一个列表,表示滑动窗口每次滑动时的最大值。
时间: 2023-12-03 07:43:23 浏览: 10
可以使用双端队列来解决这个问题。队列中存放的是当前窗口中的元素的下标,队首元素对应的是当前窗口中的最大元素。每次向右移动窗口时,先将队首元素对应的元素加入结果列表中,然后判断队尾元素对应的元素是否小于等于当前加入的元素,如果是,则将队尾元素出队,直到队列为空或者队尾元素对应的元素大于当前加入的元素,然后将当前元素的下标加入队列中。同时,如果队首元素对应的下标已经不在窗口中,也需要将其出队。下面是代码实现:
```python
nums = list(map(int, input().split()))
k = int(input())
queue = []
result = []
for i in range(len(nums)):
if queue and i - queue[0] >= k:
queue.pop(0)
while queue and nums[queue[-1]] <= nums[i]:
queue.pop()
queue.append(i)
if i >= k - 1:
result.append(nums[queue[0]])
print(result)
```
输入样例:
```
1 3 -1 -3 5 3 6 7
3
```
输出样例:
```
[3, 3, 5, 5, 6, 7]
```
相关问题
java给定一个整数数组nums,有一个大小为k的滑动窗口从数组最左侧移动到数组的最右侧,每次只向右移动一位,求每次滑动窗口内的k个数字中的最大值组成的列表
你好,这是一个典型的滑动窗口问题,可以使用双端队列来解决。
具体思路如下:
1. 初始化一个双端队列deque,用于存放数组索引
2. 遍历数组nums,对于每个元素nums[i],进行以下操作:
a. 判断队列头部的索引是否在滑动窗口内,如果不在则弹出队列头部
b. 判断队列尾部的索引对应的元素是否小于当前元素nums[i],如果是则弹出队列尾部
c. 将当前元素的索引加入队列尾部
d. 如果i>=k-1,则说明当前滑动窗口已经形成,将队列头部对应的元素加入结果列表
3. 返回结果列表
下面是Java代码实现:
```
public List<Integer> maxSlidingWindow(int[] nums, int k) {
List<Integer> result = new ArrayList<>();
Deque<Integer> deque = new LinkedList<>();
for (int i = 0; i < nums.length; i++) {
// 判断队列头部的索引是否在滑动窗口内,如果不在则弹出队列头部
if (!deque.isEmpty() && deque.peek() < i - k + 1) {
deque.poll();
}
// 判断队列尾部的索引对应的元素是否小于当前元素nums[i],如果是则弹出队列尾部
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.removeLast();
}
// 将当前元素的索引加入队列尾部
deque.offer(i);
// 如果i>=k-1,则说明当前滑动窗口已经形成,将队列头部对应的元素加入结果列表
if (i >= k - 1) {
result.add(nums[deque.peek()]);
}
}
return result;
}
```
用java语言实现以下代码:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。
以下是使用Java语言实现的代码:
```java
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0 || k == 0) {
return new int[0];
}
int n = nums.length;
int[] result = new int[n - k + 1];
Deque<Integer> deque = new LinkedList<>();
for (int i = 0; i < n; i++) {
while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
deque.pollFirst();
}
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
deque.offerLast(i);
if (i - k + 1 >= 0) {
result[i - k + 1] = nums[deque.peekFirst()];
}
}
return result;
}
```
我们使用一个双端队列 deque 来保存当前窗口内的数字,每次向右移动窗口时,我们需要在 deque 中保证:
1. deque 中的元素下标在区间 [i-k+1, i] 内,即最左侧的元素下标为 i-k+1。
2. deque 中的元素按照从大到小的顺序排列,即 deque.peekFirst() 即为当前窗口内的最大值。
具体实现过程中,我们首先将 deque 中下标不在区间 [i-k+1, i] 内的元素从队首移除。然后我们将当前数字 nums[i] 与 deque 中的最后一个元素比较,如果 nums[i] 更大,则将 deque 中的最后一个元素移除,直到 deque 中的最后一个元素比 nums[i] 大或 deque 为空为止。最后,我们将 nums[i] 的下标加入 deque 中,这样保证了 deque 中的元素下标在区间 [i-k+1, i] 内,且按照从大到小的顺序排列。并且,如果当前 i>=k-1,即窗口的大小为 k 时,我们将 deque.peekFirst() 即为当前窗口内的最大值,将其保存到结果数组中。
最后,我们返回结果数组即可。