爪哇2博客
爪哇2博客

爪哇中的滑动窗口最大值

在这篇文章中,我们将看到有关Java滑动窗口最大值的信息


问题

给定一个整数数组和一个整数k,从大小为K的所有连续子数组中找到的最大竞彩篮球分析。

例如:

输入值 :int [] rr = {2,6,-1,2,4,1,-6,5}
整数k = 3
输出 :6,6,4,4,4,5

对于每个大小为k的子数组,打印其最大竞彩篮球分析。


天真的方法:
基本的解决方案是只生成所有大小为k的连续子数组,然后遍历它们,以找出当前子数组中的最大值。
考虑到,对于每个景点,我们基本上都在考虑‘k’竞彩篮球分析,然后我们循环遍历这k个竞彩篮球分析,因此该算法最差的时间复杂度是 O(n * k).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
数组;
 
进口 爪哇.实用程序.扫描器;
 
上市 slideWindowMax {
 
上市 静态的 虚空 主要([] args) {
 
扫描器 scn = 扫描器(系统.);
整型 [] rr = 整型[scn.nextInt()];
对于(整型 i = 0; i < rr.长度; i++)
{
rr[i] = scn.nextInt();
}
整型 windowSize = scn.nextInt();
解决(rr, windowSize);
}
上市 静态的 虚空 解决(整型[] rr, 整型 k)
{
//从k开始外循环并运行直到
                //当前指针等于arr.length
对于(整型 i = k; i <= rr.长度; i++)
{
整型 最高 = 整数.MIN_VALUE;
//此循环考虑以i-1结尾的大小为k的子数组
对于(整型 j = i-k; j<i; j++)
{
最高 = 数学.最高(最高, rr[j]);
}
系统..打印(最高);
}
}
}
 

稍微有效的方法:

通过使用,我们可以肯定地减少为每个子数组找到最大值所需的时间 段树。
我们可以为给定的数组实现一个分段树,并且可以通过范围查询获得每个子数组的最大值 [i,i + k-1].

  • 段树中的节点总数 :
    构建段树的最差时间复杂度是 上) 因为我们知道
    (i)段树的叶节点包含数组的所有竞彩篮球分析。
    (ii)最后一级上的节点数是所有上一级上的节点数。
  • 数学上,
  1. 考虑数组的长度为n,因此,段树的叶节点将为n。
  2. 因此,所有较高级别上的节点数将为n-1。
  3. 长度为n的数组的分段树上的总节点数为:
    Tn =叶节点+上层节点
          = n + n-1
          = 2n+1
  • 复杂度分析

我们的分段树的构造只涉及每个节点一次的计算,因此分段树构造的最差时间复杂度为O(2n + 1),即 上)。
每个子数组的范围查询结果将在 O(logk).
查询计算将针对所有‘n-k+1’大小为k的子数组。
因此,此算法的总体时间复杂度将为O((n-k + 1)* 日志k),即 O(nlogk).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 
数组;
 
进口 爪哇.实用程序.扫描器;
 
上市 slideWindowMax {
 
静态的 整型[] 萨尔;
 
上市 静态的 虚空 主要([] args) {
 
扫描器 scn = 扫描器(系统.);
整型[] rr = 整型[scn.nextInt()];
 
对于 (整型 i = 0; i < rr.长度; i++) {
rr[i] = scn.nextInt();
}
 
整型 windowSize = scn.nextInt();
 
整型 高度 = (整型)数学.细胞((数学.日志(rr.长度) / 数学.日志(2)));
 
/ *段数组的大小  即节点数将为= [(2 ^ 高度 + 1)-1] * /
 
萨尔 = 整型[1<<高度 -1];
 
构造(0, 0, rr.长度-1, rr);
 
解决(rr, windowSize);
 
}
 
上市 静态的 虚空 解决(整型[] rr, 整型 k) {
对于 (整型 i = 0; i <= rr.长度 - k; i++) {
/ *查找从i到i + k的范围查询的结果,这基本上是一个子数组。
*
* /
系统..打印(询问(0, i, i + k - 1, 0, rr.长度 - 1));
}
}
 
上市 静态的 整型 构造(整型 IDX, 整型 开始, 整型 结束, 整型[] rr) {
/ *叶子节点包含数组竞彩篮球分析* /
如果 (开始 == 结束) {
萨尔[IDX] = rr[结束];
返回 萨尔[IDX];
}
 
整型 = (开始 + 结束) / 2;
/ *将分段树中每个节点的范围分成两半* /
整型 剩下 = 构造(2 * IDX + 1, 开始, , rr);
整型 = 构造(2 * IDX + 2, + 1, 结束, rr);
/ *将计算段树中当前索引的结果
*  以后期顺序排列,并且最多为两个孩子。
* /
萨尔[IDX] = 数学.最高(剩下, );
返回 萨尔[IDX];
}
 
上市 静态的 整型 询问(整型 IDX, 整型 询问Start, 整型 QueryEnd, 整型 开始, 整型 结束) {
/ *如果我们的范围完全不在查询范围内,
*我们需要返回一个结果,使其对我们的最终答案没有影响。
* /
 
如果 (开始 > QueryEnd || 结束 < 询问Start) {
返回 整数.MIN_VALUE;
}
/ *如果当前段的范围完全落入
*  在查询中然后返回其值。
* /
其他 如果 (开始 >= 询问Start && 结束 <= QueryEnd) {
返回 萨尔[IDX];
} 其他 {
 
整型 = (开始 + 结束) / 2;
整型 剩下 = 询问(2 * IDX + 1, 询问Start, QueryEnd, 开始, );
整型 = 询问(2 * IDX + 2, 询问Start, QueryEnd, + 1, 结束);
 
返回 数学.最高(剩下, );
}
}
}
 

最有效的方法 :

在这种方法中,我们使用 双端队列 这有助于我们找到最大的滑动窗口 上).

  • A 双端队列 基本上是一个队列,该队列在入队和出队都在两端开放,也就是说,您可以从前面或后面添加或删除竞彩篮球分析。

我们实际上要解决的问题是:

我们将子数组的k个竞彩篮球分析按相反的顺序保留,我们不需要保留所有k个竞彩篮球分析,尽管稍后我们将在代码中看到。

  • 为前k个竞彩篮球分析生成双端队列,使它们以相反的顺序排序,以使最大竞彩篮球分析位于最前面。
  • 如果Deque为空,则直接添加竞彩篮球分析,否则检查传入的竞彩篮球分析是否大于最后一个竞彩篮球分析,如果是,则从最后弹出竞彩篮球分析,直到剩余Deque的最后一个竞彩篮球分析大于传入的竞彩篮球分析。
  • 我们还需要删除哪些竞彩篮球分析 属于不同的子数组。即双端队列的索引必须在该范围内, [i,i + k].

一个竞彩篮球分析将仅在以下两种情况下被删除:
(一世) 如果即将到来的竞彩篮球分析更大 than the element at ,如果这样,它将继续弹出该竞彩篮球分析,直到剩余出队的后面有一个更大的竞彩篮球分析为止,因为我们需要保持数组以相反的顺序排序。
(ii)如果竞彩篮球分析属于 任何其他子数组 那么就没有必要保留它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 
组织.Arpit.爪哇2blog;
 
进口 爪哇.实用程序.链表;
进口 爪哇.实用程序.扫描器;
 
上市 滑动窗口最大 {
 
静态的 整型[] 萨尔;
 
上市 静态的 虚空 主要([] args) {
 
扫描器 scn = 扫描器(系统.);
整型[] rr = 整型[scn.nextInt()];
 
对于 (整型 i = 0; i < rr.长度; i++) {
rr[i] = scn.nextInt();
}
 
系统..打印(“ rr []:{”);
对于 (整型 i = 0; i < rr.长度; i++) {
系统..打印(+rr[i]);
}
 
系统..打印(“}”);
 
整型 windowSize = scn.nextInt();
 
解决效率(rr, windowSize);
 
}
 
上市 静态的 虚空 解决效率(整型[] rr, 整型 k) {
链表<整数> 双端队列 = 链表<>();
 
对于 (整型 i = 0; i < rr.长度; i++) {
 
/ *继续从双端队列移除竞彩篮球分析
*小于当前竞彩篮球分析,
*因为我们需要保持双端队列按dec顺序排序
* /
(!双端队列.是空的() && rr[双端队列.getLast()] <= rr[i]) {
双端队列.removeLast();
}
 
/ *删除i-k竞彩篮球分析,因为该竞彩篮球分析不属于
*到我们当前正在处理的子数组。
* /
(!双端队列.是空的() && 双端队列.getFirst() <= i - k) {
双端队列.removeFirst();
}
 
双端队列.addLast(i);
 
如果(i >= k-1)
{  
/ *仅在我们处理了至少k个竞彩篮球分析后才打印
*制作第一个子数组
* /
系统..打印(+rr[双端队列.getFirst()]);
}
 
}
}
}
 

当您运行上述程序时,将获得以下输出:

8
2 6 -1 2 4 1 -6 5
rr []:{2 6 -1 2 4 1 -6 5}
3
6 6 4 4 4 5

那’关于Java中最大滑动窗口的全部。


导入联系人

您可能还喜欢:

分享这个

相关文章

  • 11月29日

    超过100个Java编码面试问题

    我一直在发布有关各种主题的数据结构和编码面试问题,例如数组,队列,堆栈,二叉树,LinkedList,字符串,数字,ArrayList等。因此,我将合并一个Java编码面试问题列表以创建索引发布。每当我添加新的Java [时,我都会继续添加指向此帖子的链接[…]

  • 4月18日

    到达最后一个索引的最小跳转数

    如果您想练习数据结构和算法程序,可以阅读100多种数据结构和算法程序。在这篇文章中,我们将看到如何找到到达上一个索引的最小跳转数。问题给定一个正整数数组A(可能为零),每个索引表示[…]

  • 3月28日

    对0、1和2的数组进行排序

    如果您想练习数据结构和算法程序,可以阅读100多种数据结构和算法程序。在这篇文章中,我们将看到如何对0、1和2s的数组进行排序。我们已经看到了有关对数组中的0s和1s进行排序的文章。问题给定一个包含零的数组,[…]

  • 3月04

    通过跳转检查是否有可能到达给定数组的末尾

    如果您想练习数据结构和算法程序,可以阅读100多种数据结构和算法程序。问题给定一个具有正整数作为竞彩篮球分析的数组,该数组指示可以从数组中任何位置进行跳转的最大长度。检查是否可以[…]

  • 2月17日

    检查数组竞彩篮球分析是否连续

    如果您想练习数据结构和算法程序,可以阅读100多种数据结构和算法程序。在这篇文章中,我们将看到如何检查数组竞彩篮球分析是否连续。问题给定一个数组,我们需要检查数组是否包含连续的竞彩篮球分析。例如:输入:array [] = {5,3,4,[…]

  • 2月04日

    O(Sqrt(height))中的K元树的LCA

    如果您想练习数据结构和算法程序,可以阅读100多种数据结构和算法程序。在这篇文章中,我们将了解如何在O(Sqrt(height))中找到K元树的最低公共祖先。我们已经看到了如何在O(n)复杂度中找到n元树的LCA。给定[…]

发表评论

您的电子邮件地址不会被公开。 必需的地方已做标记 *

订阅我们的新闻

获取质量教程到您的收件箱。现在订阅。


成为朋友

©2020 爪哇2博客