• 30 Day Challenge Day 1 | Hackerrank


    题述

    原题见链接

    题解

    根据题意,很容易想到蛮力解法如下:

    Brute Force Method

    // Complete the arrayManipulation function below.
    long arrayManipulation(int n, vector<vector<int>> queries) {
        vector<long> arr(n, 0);
        long max_val = 0;
        for(auto q : queries) {
            int l = q[0]-1, r = q[1]-1;
            for(int i = l; i <= r; ++i) {
                arr[i] += q[2];
                if(max_val < arr[i]) {
                    max_val = arr[i];
                }
            }
        }
        return max_val;
    }
    

    这道题难度级别是Hard,可想而知,应该没有那么简单。提交以后没有通过所有测试用例,原因是超时。

    蛮力解法的复杂度是(O(n^2))。有没有办法降低复杂度呢?

    讨论版提示了一种方法,避免把区间内的所有元素都操作一遍,毕竟这里有一个特点是,每次区间内的元素都是加上同样的值。不妨只操作一次。

    对上面的代码做一点修改,找到区间的开始点(l)和结束点(r)以后,只在开始位置(l)加上对应值,在区间结束点的下一位(如果存在的话)减去这个对应值。

            arr[l] += q[2];
            if(r+1 < n) arr[r+1] -= q[2];
    

    这样一来,最后得到的数组通过区间求和操作得到最大指。这个方法叫做Prefix Sum Algorithm,还是第一次了解到。

    举例来说,如果输入如下:

    5 3
    1 2 100
    2 5 100
    3 4 100
    

    那么操作过程如下:

    Original: 0 0 0 0 0
    Step 1: 100 0 -100 0 0
    Step 2: 100 100 -100 0 0
    Step 3: 100 100 0 0 -100
    

    那么,子区间([0,i](i<=n))内求和得到的最大值是200,也就是所要求的结果。

    最终通过的题解如下:

    Prefix Sum Algorithm

    // Complete the arrayManipulation function below.
    long arrayManipulation(int n, vector<vector<int>> queries) {
        vector<long> arr(n, 0);
        long max_val = 0;
    
        for(auto q : queries) {
            int l = q[0]-1, r = q[1]-1;
            arr[l] += q[2];
            if(r+1 < n) arr[r+1] -= q[2];
        }
    
        long sum = 0;
        for(int i = 0; i < n; i++) {
           sum = sum + arr[i];
           if(max_val < sum) max_val = sum;
        }
    
        return max_val;
    }
    
  • 相关阅读:
    集合
    字典
    元组
    列表
    数字类型和字符串类型
    Python 数据类型
    jq的一点点
    常用到jq的ajax
    上传
    下载
  • 原文地址:https://www.cnblogs.com/casperwin/p/13228138.html
Copyright © 2020-2023  润新知