Skip to content

Commit daa7248

Browse files
committed
Monotonic queue
1 parent 6ad0a15 commit daa7248

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package datastructure.monotonicqueue;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* Title: 跳台阶 Desc: A Frog jumps K steps at most. It costs `A[i]` to stays at
7+
* `i`. Return the min cost to get to `N-1` from `0` Created by Myth on
8+
* 01/14/2020 in VSCode
9+
*/
10+
11+
public class FrogJump2 {
12+
13+
public int jump(int[] costs, int K) {
14+
int n = costs.length;
15+
int[] dp = new int[n];
16+
Arrays.fill(dp, Integer.MAX_VALUE);
17+
for (int i = 0; i <= K && i < n; i++) {
18+
dp[i] = costs[i];
19+
}
20+
21+
for (int i = K+1; i < n; i++) {
22+
for (int j = 1; j <= K; j++) {
23+
dp[i] = Math.min(dp[i], dp[i-j]+costs[i]);
24+
}
25+
}
26+
System.out.println(Arrays.toString(dp));
27+
return dp[n-1];
28+
29+
}
30+
/** 使用单调栈优化
31+
from collections import deque
32+
def min_cost(A, K):
33+
Q = deque([(0, A[0])])
34+
for i in range(1, len(A)):
35+
36+
# keep sliding width == K steps
37+
while Q and Q[0][0] < i - K:
38+
Q.popleft()
39+
40+
# remove inferior elements at the tail
41+
while Q and Q[-1][1] > A[i] + Q[0][1]:
42+
Q.pop()
43+
44+
Q.append((i, A[i] + Q[0][1]))
45+
return Q[-1][1]
46+
*
47+
*/
48+
public static void main(String[] args) {
49+
int[] costs = {0, 3, 2, 7, 1, 4};
50+
FrogJump2 frogJump2 = new FrogJump2();
51+
frogJump2.jump(costs, 2);
52+
}
53+
54+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package datastructure.monotonicqueue;
2+
3+
import java.util.ArrayDeque;
4+
import java.util.Deque;
5+
6+
/**
7+
* Title: 862. 和至少为 K 的最短子数组
8+
* Desc:
9+
* 209题(双指针)的进阶版,其中数字可以为负数,这样我们就不知道下一个数会使总和大还是小了,就不能用双指针的做法.
10+
*
11+
* 返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。如果没有和至少为 K 的非空子数组,返回 -1 。
12+
* Created by Myth on 01/14/2020 in VSCode
13+
*/
14+
15+
public class P862ShortestSubarrayWithSumAtLeastK {
16+
// 单纯 前缀和(TLE)
17+
public int shortestSubarray_Old(int[] A, int K) {
18+
int n = A.length;
19+
int[] preSum = new int[n+1]; // 前缀和
20+
int ret = n+1;
21+
for (int i = 1; i <= n; i++) {
22+
preSum[i] = preSum[i-1] + A[i-1];
23+
for (int j = 0; j < i; j++) {
24+
if (preSum[i] - preSum[j] >= K) ret = Math.min(ret, i-j);
25+
}
26+
}
27+
return ret == n+1 ? -1 : ret;
28+
}
29+
// 优化
30+
public int shortestSubarray(int[] A, int K) {
31+
int n = A.length;
32+
int[] preSum = new int[n+1];
33+
int ret = n+1;
34+
Deque<Integer> deque = new ArrayDeque<>(); // 递增队列
35+
for (int i = 0; i < n; i++) {
36+
preSum[i+1] = preSum[i] + A[i];
37+
}
38+
for (int i = 0; i <= n; i++) {
39+
while (deque.size() > 0 && preSum[i] - preSum[deque.getFirst()] >= K)
40+
ret = Math.min(ret, i - deque.pollFirst());
41+
// 使用递增队列 才能保证
42+
while (deque.size() > 0 && preSum[deque.getLast()] >= preSum[i])
43+
deque.pollLast();
44+
deque.addLast(i);
45+
}
46+
return ret == n+1 ? -1 : ret;
47+
}
48+
}

0 commit comments

Comments
 (0)