Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
GreyZeng
algorithm
提交
b38124a8
A
algorithm
项目概览
GreyZeng
/
algorithm
通知
10
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
algorithm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b38124a8
编写于
12月 08, 2022
作者:
GreyZeng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
all less num sub array
上级
fc0c2777
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
287 addition
and
384 deletion
+287
-384
src/main/java/leetcode/medium/LeetCode_0743_NetworkDelayTime.java
.../java/leetcode/medium/LeetCode_0743_NetworkDelayTime.java
+222
-233
src/main/java/nowcoder/NowCoder_AllLessNumSubArray.java
src/main/java/nowcoder/NowCoder_AllLessNumSubArray.java
+65
-0
src/main/java/snippet/Code_0087_AllLessNumSubArray.java
src/main/java/snippet/Code_0087_AllLessNumSubArray.java
+0
-151
未找到文件。
src/main/java/leetcode/medium/LeetCode_0743_NetworkDelayTime.java
浏览文件 @
b38124a8
//There are N network nodes, labelled 1 to N.
//
// Given times, a list of travel times as directed edges times[i] = (u, v, w),
// where u is the source node, v is the target node,
// and w is the time it takes for a signal to travel from source to target.
//
// Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal?
// If it is impossible, return -1.
// 有 n 个网络节点,标记为 1 到 n。
// 给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi
// 是一个信号从源节点传递到目标节点的时间。
// 现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。
package
leetcode.medium
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Map
;
// https://leetcode.cn/problems/network-delay-time/
// 笔记:
public
class
LeetCode_0743_NetworkDelayTime
{
public
static
void
main
(
String
[]
args
)
{
int
[][]
times
=
new
int
[][]{{
1
,
2
,
1
},
{
2
,
3
,
2
},
{
1
,
3
,
1
}};
int
N
=
3
;
int
K
=
2
;
System
.
out
.
println
(
networkDelayTime
(
times
,
N
,
K
));
public
static
int
networkDelayTime
(
int
[][]
times
,
int
N
,
int
K
)
{
// 转换成图结构
Graph
graph
=
generate
(
times
);
Node
from
=
null
;
// 找到开始节点
for
(
Node
n
:
graph
.
nodes
.
values
())
{
if
(
n
.
value
==
K
)
{
from
=
n
;
}
}
public
static
int
networkDelayTime
(
int
[][]
times
,
int
N
,
int
K
)
{
Graph
graph
=
generate
(
times
);
Node
from
=
null
;
for
(
Node
n
:
graph
.
nodes
.
values
())
{
if
(
n
.
value
==
K
)
{
from
=
n
;
}
}
HashMap
<
Node
,
Integer
>
map
=
dijkstra2
(
from
,
N
);
int
sum
=
-
1
;
for
(
Map
.
Entry
<
Node
,
Integer
>
entry
:
map
.
entrySet
())
{
if
(
entry
.
getValue
()
==
0
)
{
N
--;
continue
;
}
N
--;
if
(
entry
.
getValue
()
==
Integer
.
MAX_VALUE
)
{
return
-
1
;
}
else
{
sum
=
Math
.
max
(
entry
.
getValue
(),
sum
);
}
}
// 防止出现环的形状
// int[][] times = new int[][]{{1, 2, 1}, {2, 3, 2}, {1, 3, 1}};
// int N = 3;
// int K = 2;
if
(
N
!=
0
)
{
return
-
1
;
}
return
sum
;
HashMap
<
Node
,
Integer
>
map
=
dijkstra2
(
from
,
N
);
int
sum
=
-
1
;
for
(
Map
.
Entry
<
Node
,
Integer
>
entry
:
map
.
entrySet
())
{
if
(
entry
.
getValue
()
==
0
)
{
N
--;
continue
;
}
N
--;
if
(
entry
.
getValue
()
==
Integer
.
MAX_VALUE
)
{
return
-
1
;
}
else
{
sum
=
Math
.
max
(
entry
.
getValue
(),
sum
);
}
}
public
static
Graph
generate
(
int
[][]
times
)
{
Graph
graph
=
new
Graph
();
for
(
int
[]
time
:
times
)
{
int
from
=
time
[
0
];
int
to
=
time
[
1
];
int
weight
=
time
[
2
];
if
(!
graph
.
nodes
.
containsKey
(
from
))
{
graph
.
nodes
.
put
(
from
,
new
Node
(
from
));
}
if
(!
graph
.
nodes
.
containsKey
(
to
))
{
graph
.
nodes
.
put
(
to
,
new
Node
(
to
));
}
Node
fromNode
=
graph
.
nodes
.
get
(
from
);
Node
toNode
=
graph
.
nodes
.
get
(
to
);
Edge
fromToEdge
=
new
Edge
(
weight
,
fromNode
,
toNode
);
//Edge toFromEdge = new Edge(weight, toNode, fromNode);
fromNode
.
nexts
.
add
(
toNode
);
fromNode
.
out
++;
//fromNode.in++;
//toNode.out++;
toNode
.
in
++;
fromNode
.
edges
.
add
(
fromToEdge
);
//toNode.edges.add(toFromEdge);
graph
.
edges
.
add
(
fromToEdge
);
//graph.edges.add(toFromEdge);
}
return
graph
;
// 防止出现环的形状
// int[][] times = new int[][]{{1, 2, 1}, {2, 3, 2}, {1, 3, 1}};
// int N = 3;
// int K = 2;
if
(
N
!=
0
)
{
return
-
1
;
}
return
sum
;
}
// 二维数组转换成自己熟悉的图结构
public
static
Graph
generate
(
int
[][]
times
)
{
Graph
graph
=
new
Graph
();
for
(
int
[]
time
:
times
)
{
int
from
=
time
[
0
];
int
to
=
time
[
1
];
int
weight
=
time
[
2
];
if
(!
graph
.
nodes
.
containsKey
(
from
))
{
graph
.
nodes
.
put
(
from
,
new
Node
(
from
));
}
if
(!
graph
.
nodes
.
containsKey
(
to
))
{
graph
.
nodes
.
put
(
to
,
new
Node
(
to
));
}
Node
fromNode
=
graph
.
nodes
.
get
(
from
);
Node
toNode
=
graph
.
nodes
.
get
(
to
);
Edge
fromToEdge
=
new
Edge
(
weight
,
fromNode
,
toNode
);
// Edge toFromEdge = new Edge(weight, toNode, fromNode);
fromNode
.
nexts
.
add
(
toNode
);
fromNode
.
out
++;
// fromNode.in++;
// toNode.out++;
toNode
.
in
++;
fromNode
.
edges
.
add
(
fromToEdge
);
// toNode.edges.add(toFromEdge);
graph
.
edges
.
add
(
fromToEdge
);
// graph.edges.add(toFromEdge);
}
public
static
class
Graph
{
public
HashMap
<
Integer
,
Node
>
nodes
;
public
HashSet
<
Edge
>
edges
;
return
graph
;
}
public
Graph
()
{
nodes
=
new
HashMap
<>();
edges
=
new
HashSet
<>();
}
public
static
class
Graph
{
public
HashMap
<
Integer
,
Node
>
nodes
;
public
HashSet
<
Edge
>
edges
;
public
Graph
()
{
nodes
=
new
HashMap
<>();
edges
=
new
HashSet
<>();
}
}
public
static
class
Edge
{
public
int
weight
;
public
Node
from
;
public
Node
to
;
public
static
class
Edge
{
public
int
weight
;
public
Node
from
;
public
Node
to
;
public
Edge
(
int
weight
,
Node
from
,
Node
to
)
{
this
.
weight
=
weight
;
this
.
from
=
from
;
this
.
to
=
to
;
}
public
Edge
(
int
weight
,
Node
from
,
Node
to
)
{
this
.
weight
=
weight
;
this
.
from
=
from
;
this
.
to
=
to
;
}
}
public
static
class
Node
{
public
int
value
;
public
int
in
;
public
int
out
;
public
ArrayList
<
Node
>
nexts
;
public
ArrayList
<
Edge
>
edges
;
public
static
class
Node
{
public
int
value
;
public
int
in
;
public
int
out
;
public
ArrayList
<
Node
>
nexts
;
public
ArrayList
<
Edge
>
edges
;
public
Node
(
int
value
)
{
this
.
value
=
value
;
in
=
0
;
out
=
0
;
nexts
=
new
ArrayList
<>();
edges
=
new
ArrayList
<>();
}
public
Node
(
int
value
)
{
this
.
value
=
value
;
in
=
0
;
out
=
0
;
nexts
=
new
ArrayList
<>();
edges
=
new
ArrayList
<>();
}
}
public
static
HashMap
<
Node
,
Integer
>
dijkstra
(
Node
from
)
{
HashMap
<
Node
,
Integer
>
distanceMap
=
new
HashMap
<>();
distanceMap
.
put
(
from
,
0
);
HashSet
<
Node
>
selectedNodes
=
new
HashSet
<>();
Node
minNode
=
getMinNode
(
distanceMap
,
selectedNodes
);
while
(
minNode
!=
null
)
{
int
distance
=
distanceMap
.
get
(
minNode
);
for
(
Edge
neighbor
:
minNode
.
edges
)
{
Node
to
=
neighbor
.
to
;
if
(!
distanceMap
.
containsKey
(
to
))
{
distanceMap
.
put
(
to
,
distance
+
neighbor
.
weight
);
}
else
{
distanceMap
.
put
(
to
,
Math
.
min
(
distance
+
neighbor
.
weight
,
distanceMap
.
get
(
to
)));
}
}
selectedNodes
.
add
(
minNode
);
minNode
=
getMinNode
(
distanceMap
,
selectedNodes
);
public
static
HashMap
<
Node
,
Integer
>
dijkstra
(
Node
from
)
{
HashMap
<
Node
,
Integer
>
distanceMap
=
new
HashMap
<>();
distanceMap
.
put
(
from
,
0
);
HashSet
<
Node
>
selectedNodes
=
new
HashSet
<>();
Node
minNode
=
getMinNode
(
distanceMap
,
selectedNodes
);
while
(
minNode
!=
null
)
{
int
distance
=
distanceMap
.
get
(
minNode
);
for
(
Edge
neighbor
:
minNode
.
edges
)
{
Node
to
=
neighbor
.
to
;
if
(!
distanceMap
.
containsKey
(
to
))
{
distanceMap
.
put
(
to
,
distance
+
neighbor
.
weight
);
}
else
{
distanceMap
.
put
(
to
,
Math
.
min
(
distance
+
neighbor
.
weight
,
distanceMap
.
get
(
to
)));
}
return
distanceMap
;
}
selectedNodes
.
add
(
minNode
);
minNode
=
getMinNode
(
distanceMap
,
selectedNodes
);
}
return
distanceMap
;
}
public
static
Node
getMinNode
(
HashMap
<
Node
,
Integer
>
distanceMap
,
HashSet
<
Node
>
selectedNodes
)
{
int
minDistance
=
Integer
.
MAX_VALUE
;
Node
minNode
=
null
;
for
(
Map
.
Entry
<
Node
,
Integer
>
entry
:
distanceMap
.
entrySet
())
{
Node
n
=
entry
.
getKey
();
int
distance
=
entry
.
getValue
();
if
(!
selectedNodes
.
contains
(
n
)
&&
distance
<
minDistance
)
{
minDistance
=
distance
;
minNode
=
n
;
}
}
return
minNode
;
public
static
Node
getMinNode
(
HashMap
<
Node
,
Integer
>
distanceMap
,
HashSet
<
Node
>
selectedNodes
)
{
int
minDistance
=
Integer
.
MAX_VALUE
;
Node
minNode
=
null
;
for
(
Map
.
Entry
<
Node
,
Integer
>
entry
:
distanceMap
.
entrySet
())
{
Node
n
=
entry
.
getKey
();
int
distance
=
entry
.
getValue
();
if
(!
selectedNodes
.
contains
(
n
)
&&
distance
<
minDistance
)
{
minDistance
=
distance
;
minNode
=
n
;
}
}
return
minNode
;
}
public
static
class
NodeRecord
{
public
Node
node
;
public
int
distance
;
public
static
class
NodeRecord
{
public
Node
node
;
public
int
distance
;
public
NodeRecord
(
Node
node
,
int
distance
)
{
this
.
node
=
node
;
this
.
distance
=
distance
;
}
public
NodeRecord
(
Node
node
,
int
distance
)
{
this
.
node
=
node
;
this
.
distance
=
distance
;
}
}
public
static
class
NodeHeap
{
private
Node
[]
nodes
;
// 实际的堆结构
// key 某一个node, value 上面堆中的位置
private
HashMap
<
Node
,
Integer
>
heapIndexMap
;
// key 某一个节点, value 从源节点出发到该节点的目前最小距离
private
HashMap
<
Node
,
Integer
>
distanceMap
;
private
int
size
;
// 堆上有多少个点
public
static
class
NodeHeap
{
private
Node
[]
nodes
;
// 实际的堆结构
// key 某一个node, value 上面堆中的位置
private
HashMap
<
Node
,
Integer
>
heapIndexMap
;
// key 某一个节点, value 从源节点出发到该节点的目前最小距离
private
HashMap
<
Node
,
Integer
>
distanceMap
;
private
int
size
;
// 堆上有多少个点
public
NodeHeap
(
int
size
)
{
nodes
=
new
Node
[
size
];
heapIndexMap
=
new
HashMap
<>();
distanceMap
=
new
HashMap
<>();
size
=
0
;
}
public
NodeHeap
(
int
size
)
{
nodes
=
new
Node
[
size
];
heapIndexMap
=
new
HashMap
<>();
distanceMap
=
new
HashMap
<>();
}
public
boolean
isEmpty
()
{
return
size
==
0
;
}
public
boolean
isEmpty
()
{
return
size
==
0
;
}
// 有一个点叫node,现在发现了一个从源节点出发到达node的距离为distance
// 判断要不要更新,如果需要的话,就更新
public
void
addOrUpdateOrIgnore
(
Node
node
,
int
distance
)
{
if
(
inHeap
(
node
))
{
distanceMap
.
put
(
node
,
Math
.
min
(
distanceMap
.
get
(
node
),
distance
));
insertHeapify
(
node
,
heapIndexMap
.
get
(
node
));
}
if
(!
isEntered
(
node
))
{
nodes
[
size
]
=
node
;
heapIndexMap
.
put
(
node
,
size
);
distanceMap
.
put
(
node
,
distance
);
insertHeapify
(
node
,
size
++);
}
}
// 有一个点叫node,现在发现了一个从源节点出发到达node的距离为distance
// 判断要不要更新,如果需要的话,就更新
public
void
addOrUpdateOrIgnore
(
Node
node
,
int
distance
)
{
if
(
inHeap
(
node
))
{
distanceMap
.
put
(
node
,
Math
.
min
(
distanceMap
.
get
(
node
),
distance
));
insertHeapify
(
node
,
heapIndexMap
.
get
(
node
));
}
if
(!
isEntered
(
node
))
{
nodes
[
size
]
=
node
;
heapIndexMap
.
put
(
node
,
size
);
distanceMap
.
put
(
node
,
distance
);
insertHeapify
(
node
,
size
++);
}
}
public
NodeRecord
pop
()
{
NodeRecord
nodeRecord
=
new
NodeRecord
(
nodes
[
0
],
distanceMap
.
get
(
nodes
[
0
]));
swap
(
0
,
size
-
1
);
heapIndexMap
.
put
(
nodes
[
size
-
1
],
-
1
);
distanceMap
.
remove
(
nodes
[
size
-
1
]);
// free C++同学还要把原本堆顶节点析构,对java同学不必
nodes
[
size
-
1
]
=
null
;
heapify
(
0
,
--
size
);
return
nodeRecord
;
}
public
NodeRecord
pop
()
{
NodeRecord
nodeRecord
=
new
NodeRecord
(
nodes
[
0
],
distanceMap
.
get
(
nodes
[
0
]));
swap
(
0
,
size
-
1
);
heapIndexMap
.
put
(
nodes
[
size
-
1
],
-
1
);
distanceMap
.
remove
(
nodes
[
size
-
1
]);
// free C++同学还要把原本堆顶节点析构,对java同学不必
nodes
[
size
-
1
]
=
null
;
heapify
(
0
,
--
size
);
return
nodeRecord
;
}
private
void
insertHeapify
(
Node
node
,
int
index
)
{
while
(
distanceMap
.
get
(
nodes
[
index
])
<
distanceMap
.
get
(
nodes
[(
index
-
1
)
/
2
]))
{
swap
(
index
,
(
index
-
1
)
/
2
);
index
=
(
index
-
1
)
/
2
;
}
}
private
void
insertHeapify
(
Node
node
,
int
index
)
{
while
(
distanceMap
.
get
(
nodes
[
index
])
<
distanceMap
.
get
(
nodes
[(
index
-
1
)
/
2
]))
{
swap
(
index
,
(
index
-
1
)
/
2
);
index
=
(
index
-
1
)
/
2
;
}
}
private
void
heapify
(
int
index
,
int
size
)
{
int
left
=
index
*
2
+
1
;
while
(
left
<
size
)
{
int
smallest
=
left
+
1
<
size
&&
distanceMap
.
get
(
nodes
[
left
+
1
])
<
distanceMap
.
get
(
nodes
[
left
])
?
left
+
1
:
left
;
smallest
=
distanceMap
.
get
(
nodes
[
smallest
])
<
distanceMap
.
get
(
nodes
[
index
])
?
smallest
:
index
;
if
(
smallest
==
index
)
{
break
;
}
swap
(
smallest
,
index
);
index
=
smallest
;
left
=
index
*
2
+
1
;
}
private
void
heapify
(
int
index
,
int
size
)
{
int
left
=
index
*
2
+
1
;
while
(
left
<
size
)
{
int
smallest
=
left
+
1
<
size
&&
distanceMap
.
get
(
nodes
[
left
+
1
])
<
distanceMap
.
get
(
nodes
[
left
])
?
left
+
1
:
left
;
smallest
=
distanceMap
.
get
(
nodes
[
smallest
])
<
distanceMap
.
get
(
nodes
[
index
])
?
smallest
:
index
;
if
(
smallest
==
index
)
{
break
;
}
swap
(
smallest
,
index
);
index
=
smallest
;
left
=
index
*
2
+
1
;
}
}
private
boolean
isEntered
(
Node
node
)
{
return
heapIndexMap
.
containsKey
(
node
);
}
private
boolean
isEntered
(
Node
node
)
{
return
heapIndexMap
.
containsKey
(
node
);
}
private
boolean
inHeap
(
Node
node
)
{
return
isEntered
(
node
)
&&
heapIndexMap
.
get
(
node
)
!=
-
1
;
}
private
boolean
inHeap
(
Node
node
)
{
return
isEntered
(
node
)
&&
heapIndexMap
.
get
(
node
)
!=
-
1
;
}
private
void
swap
(
int
index1
,
int
index2
)
{
heapIndexMap
.
put
(
nodes
[
index1
],
index2
);
heapIndexMap
.
put
(
nodes
[
index2
],
index1
);
Node
tmp
=
nodes
[
index1
];
nodes
[
index1
]
=
nodes
[
index2
];
nodes
[
index2
]
=
tmp
;
}
private
void
swap
(
int
index1
,
int
index2
)
{
heapIndexMap
.
put
(
nodes
[
index1
],
index2
);
heapIndexMap
.
put
(
nodes
[
index2
],
index1
);
Node
tmp
=
nodes
[
index1
];
nodes
[
index1
]
=
nodes
[
index2
];
nodes
[
index2
]
=
tmp
;
}
}
// 改进后的dijkstra算法
// 从head出发,所有head能到达的节点,生成到达每个节点的最小路径记录并返回
public
static
HashMap
<
Node
,
Integer
>
dijkstra2
(
Node
head
,
int
size
)
{
NodeHeap
nodeHeap
=
new
NodeHeap
(
size
);
nodeHeap
.
addOrUpdateOrIgnore
(
head
,
0
);
HashMap
<
Node
,
Integer
>
result
=
new
HashMap
<>();
while
(!
nodeHeap
.
isEmpty
())
{
NodeRecord
record
=
nodeHeap
.
pop
();
Node
cur
=
record
.
node
;
int
distance
=
record
.
distance
;
for
(
Edge
edge
:
cur
.
edges
)
{
nodeHeap
.
addOrUpdateOrIgnore
(
edge
.
to
,
edge
.
weight
+
distance
);
}
result
.
put
(
cur
,
distance
);
}
return
result
;
// 改进后的dijkstra算法
// 从head出发,所有head能到达的节点,生成到达每个节点的最小路径记录并返回
public
static
HashMap
<
Node
,
Integer
>
dijkstra2
(
Node
head
,
int
size
)
{
NodeHeap
nodeHeap
=
new
NodeHeap
(
size
);
nodeHeap
.
addOrUpdateOrIgnore
(
head
,
0
);
HashMap
<
Node
,
Integer
>
result
=
new
HashMap
<>();
while
(!
nodeHeap
.
isEmpty
())
{
NodeRecord
record
=
nodeHeap
.
pop
();
Node
cur
=
record
.
node
;
int
distance
=
record
.
distance
;
for
(
Edge
edge
:
cur
.
edges
)
{
nodeHeap
.
addOrUpdateOrIgnore
(
edge
.
to
,
edge
.
weight
+
distance
);
}
result
.
put
(
cur
,
distance
);
}
return
result
;
}
}
src/main/java/nowcoder/NowCoder_AllLessNumSubArray.java
0 → 100644
浏览文件 @
b38124a8
// 链接:https://www.nowcoder.com/questionTerminal/5fe02eb175974e18b9a546812a17428e
// 来源:牛客网
//
// 给定数组 arr 和整数 num,共返回有多少个子数组满足如下情况:
// max(arr[i...j]) - min(arr[i...j]) <= num
// max(arr[i...j])表示子数组arr[i...j]中的最大值,min[arr[i...j])表示子数组arr[i...j]中的最小值。
package
nowcoder
;
import
java.util.LinkedList
;
import
java.util.Scanner
;
// 笔记:https://www.cnblogs.com/greyzeng/p/16966417.html
// arr[L..R]达标,则arr中内部的任何一个子数组都达标
// arr[L..R]不达标,则arr扩充后肯定也不达标
// L...R 范围如果达标,其子数组个数为:R - L
public
class
NowCoder_AllLessNumSubArray
{
// 必须以l位置作为左边界的情况下,有多少达标的数组
public
static
int
getNum
(
int
[]
arr
,
int
num
)
{
LinkedList
<
Integer
>
qMax
=
new
LinkedList
<>();
LinkedList
<
Integer
>
qMin
=
new
LinkedList
<>();
int
ans
=
0
;
int
l
=
0
;
int
r
=
0
;
while
(
l
<
arr
.
length
)
{
while
(
r
<
arr
.
length
)
{
while
(!
qMax
.
isEmpty
()
&&
arr
[
qMax
.
peekLast
()]
<=
arr
[
r
])
{
qMax
.
pollLast
();
}
qMax
.
addLast
(
r
);
while
(!
qMin
.
isEmpty
()
&&
arr
[
qMin
.
peekLast
()]
>=
arr
[
r
])
{
qMin
.
pollLast
();
}
qMin
.
addLast
(
r
);
if
(
arr
[
qMax
.
peekFirst
()]
-
arr
[
qMin
.
peekFirst
()]
>
num
)
{
break
;
}
r
++;
}
// r是以l作为左边界,第一个不满足条件的位置
ans
+=
(
r
-
l
);
// 弹出过期位置
if
(!
qMax
.
isEmpty
()
&&
qMax
.
peekFirst
()
==
l
)
{
qMax
.
pollFirst
();
}
// 弹出过期位置
if
(!
qMin
.
isEmpty
()
&&
qMin
.
peekFirst
()
==
l
)
{
qMin
.
pollFirst
();
}
l
++;
}
return
ans
;
}
public
static
void
main
(
String
[]
args
)
{
Scanner
in
=
new
Scanner
(
System
.
in
);
int
n
=
in
.
nextInt
();
int
m
=
in
.
nextInt
();
int
[]
arr
=
new
int
[
n
];
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
arr
[
i
]
=
in
.
nextInt
();
}
System
.
out
.
println
(
getNum
(
arr
,
m
));
in
.
close
();
}
}
src/main/java/snippet/Code_0087_AllLessNumSubArray.java
已删除
100644 → 0
浏览文件 @
fc0c2777
//链接:https://www.nowcoder.com/questionTerminal/5fe02eb175974e18b9a546812a17428e
// 来源:牛客网
//
// 给定数组 arr 和整数 num,共返回有多少个子数组满足如下情况:
// max(arr[i...j]) - min(arr[i...j]) <= num
// max(arr[i...j])表示子数组arr[i...j]中的最大值,min[arr[i...j])表示子数组arr[i...j]中的最小值。
//
//
// 输入描述:
//
// 第一行输入两个数 n 和 num,其中 n 表示数组 arr 的长度
// 第二行输入n个整数XiX_iXi,表示数组arr中的每个元素
//
//
//
// 输出描述:
//
// 输出给定数组中满足条件的子数组个数
//
// 示例1
// 输入
//
// 5 2
// 1 2 3 4 5
//
// 输出
//
// 12
//
//
// 备注:
//
// 1≤n≤1000000
// −1000000≤arri≤1000000
// 0≤num≤20000000
package
snippet
;
import
java.util.LinkedList
;
// arr[L..R]达标,则arr中内部的任何一个子数组都达标
// arr[L..R]不达标,则arr扩充后肯定也不达标
// L...R 范围如果达标,其子数组个数为:R - L
public
class
Code_0087_AllLessNumSubArray
{
// 必须以l位置作为左边界的情况下,有多少达标的数组
public
static
int
getNum
(
int
[]
arr
,
int
num
)
{
LinkedList
<
Integer
>
qMax
=
new
LinkedList
<>();
LinkedList
<
Integer
>
qMin
=
new
LinkedList
<>();
int
ans
=
0
;
int
l
=
0
;
int
r
=
0
;
while
(
l
<
arr
.
length
)
{
while
(
r
<
arr
.
length
)
{
while
(!
qMax
.
isEmpty
()
&&
arr
[
qMax
.
peekLast
()]
<=
arr
[
r
])
{
qMax
.
pollLast
();
}
qMax
.
addLast
(
r
);
while
(!
qMin
.
isEmpty
()
&&
arr
[
qMin
.
peekLast
()]
>=
arr
[
r
])
{
qMin
.
pollLast
();
}
qMin
.
addLast
(
r
);
if
(
arr
[
qMax
.
peekFirst
()]
-
arr
[
qMin
.
peekFirst
()]
>
num
)
{
break
;
}
r
++;
}
// r是以l作为左边界,第一个不满足条件的位置
ans
+=
(
r
-
l
);
// 弹出过期位置
if
(!
qMax
.
isEmpty
()
&&
qMax
.
peekFirst
()
==
l
)
{
qMax
.
pollFirst
();
}
// 弹出过期位置
if
(!
qMin
.
isEmpty
()
&&
qMin
.
peekFirst
()
==
l
)
{
qMin
.
pollFirst
();
}
l
++;
}
return
ans
;
}
// 暴力的对数器方法
public
static
int
right
(
int
[]
arr
,
int
sum
)
{
if
(
arr
==
null
||
arr
.
length
==
0
||
sum
<
0
)
{
return
0
;
}
int
N
=
arr
.
length
;
int
count
=
0
;
for
(
int
L
=
0
;
L
<
N
;
L
++)
{
for
(
int
R
=
L
;
R
<
N
;
R
++)
{
int
max
=
arr
[
L
];
int
min
=
arr
[
L
];
for
(
int
i
=
L
+
1
;
i
<=
R
;
i
++)
{
max
=
Math
.
max
(
max
,
arr
[
i
]);
min
=
Math
.
min
(
min
,
arr
[
i
]);
}
if
(
max
-
min
<=
sum
)
{
count
++;
}
}
}
return
count
;
}
// for test
public
static
int
[]
generateRandomArray
(
int
maxLen
,
int
maxValue
)
{
int
len
=
(
int
)
(
Math
.
random
()
*
(
maxLen
+
1
));
int
[]
arr
=
new
int
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
arr
[
i
]
=
(
int
)
(
Math
.
random
()
*
(
maxValue
+
1
))
-
(
int
)
(
Math
.
random
()
*
(
maxValue
+
1
));
}
return
arr
;
}
// for test
public
static
void
printArray
(
int
[]
arr
)
{
if
(
arr
!=
null
)
{
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++)
{
System
.
out
.
print
(
arr
[
i
]
+
" "
);
}
System
.
out
.
println
();
}
}
public
static
void
main
(
String
[]
args
)
{
int
maxLen
=
100
;
int
maxValue
=
200
;
int
testTime
=
100000
;
System
.
out
.
println
(
"测试开始"
);
for
(
int
i
=
0
;
i
<
testTime
;
i
++)
{
int
[]
arr
=
generateRandomArray
(
maxLen
,
maxValue
);
int
sum
=
(
int
)
(
Math
.
random
()
*
(
maxValue
+
1
));
int
ans1
=
right
(
arr
,
sum
);
int
ans2
=
getNum
(
arr
,
sum
);
if
(
ans1
!=
ans2
)
{
System
.
out
.
println
(
"Oops!"
);
printArray
(
arr
);
System
.
out
.
println
(
sum
);
System
.
out
.
println
(
ans1
);
System
.
out
.
println
(
ans2
);
break
;
}
}
System
.
out
.
println
(
"测试结束"
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录