题目是LeetCode2020春季全国编程大赛个人赛的第三题,链接:LCP 08. 剧情触发时间。具体描述见原题。
这道题是medium难度的,不过当时我在这道题花了最多时间,因为直接暴力会超时的,需要优化。当时想到的方法就是直接用另外一个数组A
来记录要使得累加和不小于一个数i
需要多少次,记录为A[i]
,因为题目中数字的范围限定了i
的最大值只可能是100000
,所以可以用定长的数组来记录,当然最好的方法还是根据最大累加和来new
数组,这里就是这么做的。假设requirements
数组的长度为N
,N
的最大值恰好就是累加和可能的最大值,因此时间复杂度为
O
(
N
)
O(N)
O(N),空间复杂度为
O
(
N
)
O(N)
O(N)。
JAVA版代码如下:
class Solution {
public int[] getTriggerTime(int[][] increase, int[][] requirements) {
int N = increase.length;
// 原地操作,计算累加和
for (int i = 1; i < N; ++i) {
for (int j = 0; j < 3; ++j) {
increase[i][j] += increase[i - 1][j];
}
}
// 大于等于i至少需要c[i]/r[i]/h[i]次
int[] c = new int[increase[N - 1][0] + 1];
int[] r = new int[increase[N - 1][1] + 1];
int[] h = new int[increase[N - 1][2] + 1];
int count = 1;
for (int i = 1; i <= increase[0][0]; ++i) {
c[i] = count;
}
for (int i = 1; i <= increase[0][1]; ++i) {
r[i] = count;
}
for (int i = 1; i <= increase[0][2]; ++i) {
h[i] = count;
}
for (int i = 1; i < N; ++i) {
++count;
// 注意如果increase为0的话就不用修改次数了
if (increase[i][0] > increase[i - 1][0]) {
for (int j = increase[i][0]; j > 0 && c[j] == 0; --j) {
c[j] = count;
}
}
if (increase[i][1] > increase[i - 1][1]) {
for (int j = increase[i][1]; j > 0 && r[j] == 0; --j) {
r[j] = count;
}
}
if (increase[i][2] > increase[i - 1][2]) {
for (int j = increase[i][2]; j > 0 && h[j] == 0; --j) {
h[j] = count;
}
}
}
int[] result = new int[requirements.length];
int idx = 0;
for (int[] require : requirements) {
if (require[0] > increase[N - 1][0] || require[1] > increase[N - 1][1] || require[2] > increase[N - 1][2]) {
result[idx++] = -1;
continue;
}
result[idx++] = Math.max(c[require[0]], Math.max(r[require[1]], h[require[2]]));
}
return result;
}
}
提交结果如下:
Python版代码如下:
class Solution:
def getTriggerTime(self, increase: List[List[int]], requirements: List[List[int]]) -> List[int]:
N = len(increase)
for i in range(1, N):
for j in range(3):
increase[i][j] += increase[i - 1][j]
c = [0] * (increase[N - 1][0] + 1)
r = [0] * (increase[N - 1][1] + 1)
h = [0] * (increase[N - 1][2] + 1)
count = 1
for i in range(1, increase[0][0] + 1):
c[i] = count
for i in range(1, increase[0][1] + 1):
r[i] = count
for i in range(1, increase[0][2] + 1):
h[i] = count
for i in range(1, N):
count += 1
if increase[i][0] > increase[i - 1][0]:
for j in range(increase[i][0], 0, -1):
if c[j] != 0:
break
c[j] = count
if increase[i][1] > increase[i - 1][1]:
for j in range(increase[i][1], 0, -1):
if r[j] != 0:
break
r[j] = count
if increase[i][2] > increase[i - 1][2]:
for j in range(increase[i][2], 0, -1):
if h[j] != 0:
break
h[j] = count
result = []
for require in requirements:
if require[0] > increase[N - 1][0] or require[1] > increase[N - 1][1] or require[2] > increase[N - 1][2]:
result.append(-1)
continue
result.append(max(c[require[0]], max(r[require[1]], h[require[2]])))
return result
提交结果如下: