leetcode-LCP 08. 剧情触发时间

 题目是LeetCode2020春季全国编程大赛个人赛的第三题,链接:LCP 08. 剧情触发时间。具体描述见原题。

 这道题是medium难度的,不过当时我在这道题花了最多时间,因为直接暴力会超时的,需要优化。当时想到的方法就是直接用另外一个数组A来记录要使得累加和不小于一个数i需要多少次,记录为A[i],因为题目中数字的范围限定了i的最大值只可能是100000,所以可以用定长的数组来记录,当然最好的方法还是根据最大累加和来new数组,这里就是这么做的。假设requirements数组的长度为NN的最大值恰好就是累加和可能的最大值,因此时间复杂度为 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

 提交结果如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值