• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

数组和窗口-贪心算法

开发技术 开发技术 2周前 (04-08) 6次浏览
Description
给定一个整型数组arr和一个大小为w的窗口,窗口从数组最左边滑动到最右边,每次向右滑动一个位置,求出每一次滑动时窗口内最大元素的和。
Input
输入第一行为用例个数, 每个测试用例输入的第一行为数组,每一个元素使用空格隔开;第二行为窗口大小。
Output
输出每个测试用例结果。
Sample Input 1 
1 4 3 5 4 3 3 6 7 3
Sample Output 1
32
 
解题思路:
使用双端队列去存储窗口内的元素。贪心策略:每次窗口新增元素,只保留比该元素更大的值,其他的因为没有作用全部删除。
窗口每移动一格,就将新元素x插入队列尾部,如果x前面元素有更小的,则在x出窗口前无法起到作用,可以全部出队。
移出窗口的元素y判断是否是队列首部元素,如果是,则出队,如果不是,说明在队列中之前就被清除了。
 
代码如下:
 1 import java.util.*;
 2 
 3 public class Main { // 注意类名必须为Main
 4     public static void main(String[] args) {
 5         Scanner scan = new Scanner(System.in);
 6         int number = Integer.parseInt(scan.nextLine());
 7         // number个测试样例
 8         for (int k = 0; k < number; k++){
 9             // 输入数据
10             String str = scan.nextLine();
11             int w = Integer.parseInt(scan.nextLine());
12             String[] strs = str.split(" ");
13             int n = strs.length;
14             if (w > n) w = n;
15             int[] arr = new int[n];
16             for (int i = 0; i < n; i++)
17                 arr[i] = Integer.parseInt(strs[i]);
18             // 双端队列,这里只存储元素的下标
19             LinkedList<Integer> list = new LinkedList<>();
20             // 初始化
21             list.addLast(0);
22 
23             for (int i = 1; i < w; i++) {
24                 while (list.size() > 0 && arr[list.getLast()] < arr[i])
25                     list.pollLast();
26                 list.addLast(i);
27             }
28             int sum = arr[list.getFirst()];
29             // 窗口移动,增加元素arr[i],除去元素arr[i-w]
30             for (int i = w; i < n; i++) {
31                 // 增加元素arr[i]
32                 while (list.size() > 0 && arr[list.peekLast()] < arr[i])
33                     list.pollLast();
34                 list.addLast(i);
35                 // 除去元素arr[i-w]
36                 if (list.getFirst() == i-w)
37                     list.pollFirst();
38                 sum += arr[list.getFirst()];
39             }
40             System.out.println(sum);
41         }
42         scan.close();
43     }
44 
45 }

 


程序员灯塔
转载请注明原文链接:数组和窗口-贪心算法
喜欢 (0)