Saturday, January 26, 2019

Array Manipulation - Hacker Rank Solution

Array Manipulation - Hacker Rank Solution

Starting with a 1-indexed array of zeros and a list of operations, for each operation add a value to each of the array element between two given indices, inclusive. Once all operations have been performed, return the maximum value in your array.

For example, the length of your array of zeros . Your list of queries is as follows:
    a b k
    1 5 3
    4 8 7
    6 9 1
Add the values of  between the indices  and  inclusive:
index->  1 2 3  4  5 6 7 8 9 10
 [0,0,0, 0, 0,0,0,0,0, 0]
 [3,3,3, 3, 3,0,0,0,0, 0]
 [3,3,3,10,10,7,7,7,0, 0]
 [3,3,3,10,10,8,8,8,1, 0]
The largest value is  after all operations are performed.
Function Description
Complete the function arrayManipulation in the editor below. It must return an integer, the maximum value in the resulting array.
arrayManipulation has the following parameters:
  • n - the number of elements in your array
  • queries - a two dimensional array of queries where each queries[i] contains three integers, ab, and k.
Input Format
The first line contains two space-separated integers  and , the size of the array and the number of operations. 
Each of the next  lines contains three space-separated integers  and , the left index, right index and summand.
Constraints
Output Format
Return the integer maximum value in the finished array.
Sample Input
5 3
1 2 100
2 5 100
3 4 100
Sample Output
200
Explanation
After the first update list will be 100 100 0 0 0
After the second update list will be 100 200 100 100 100
After the third update list will be 100 200 200 200 100
The required answer will be .

Array Manipulation - Hacker Rank Solution
You are given a list of size n, initialized with zeroes. You have to perform m queries on the list and output the maximum of final values of all the n elements in the list. For every query, you are given three integers a, b and k and you have to add value k to all the elements ranging from index a to b(both inclusive).
Sub-Optimal Brute Force:
Given each update , for each index in the range from [], add the value  to each number in the range.
The final step is to go through the whole array and find the maximum value and print that maximum value.
The complexity of this solution is O() which is too high to pass in time.
Optimal:
  • Given a range[] and a value  we need to add  to all the numbers whose indices are in the range from [].
  • We can do an O() update by adding  to index  and add  to index .
  • Doing this kind of update, the  number in the array will be prefix sum of array from index 1 to i because we are adding to the value at index  and subtracting  from the value at index  and taking prefix sum will give us the actual value for each index after  operations .
  • So, we can do all  updates in O(m) time. Now we have to check the largest number in the original array. i.e. the index i such that prefix sum attains the maximum value.
  • We can calculate all prefix sums as well as maximum prefix sum in O(n) time which will execute in time.
Optimal:
  • This can be further optimized to run in O(m logm) time because we have to check the value of prefix sum at only indices. i.e.  and  values of all the updates.
  • We have, in total  queries and each query has a range [] which needs to be updated. So, in total we have indices.
  • For each query, we can insert both  and  in an array and sort the array.
  • Now, we have to just take the prefix sum of the array and find the maximum element which will be our answer.
    Check the setter's code for better understanding.
Note: If you thought of solving it using segment tree with lazy propogation, it won't pass here as  can be as high as .
Problem Setter's code:
#include <bits/stdc++.h>

using namespace std;
long a[400009];

int main() {
    
    int n;
    int m;
    cin >> n >> m;
    vector < pair < int, int > > v;
    
    for(int a0 = 0; a0 < m; a0++) {
    
        int a;
        int b;
        int k;
        cin >> a >> b >> k;
        
        //storing the query
        //this will add k in the prefix sum for index >= a
        v.push_back(make_pair(a, k));
        
        //adding -1*k will remove k from the prefix sum for index > b 
        v.push_back(make_pair(b+1, -1 * k));
    }
    
    long mx = 0, sum = 0;
    
    sort(v.begin(), v.end());
    
    for(int i=0 ; i<2*m; i++) {
    
        sum += v[i].second;
        mx = max(mx, sum);
        
    }
        
    cout<<mx<<endl;
    return 0;
}

Problem Tester's code:
#include <bits/stdc++.h>

using namespace std;
long a[400009];

int main() {

    int n;
    int m;
    cin >> n >> m;
    vector < pair < int, int > > v;

 for(int a0 = 0; a0 < m; a0++) {
    
        int a;
        int b;
        int k;
        cin >> a >> b >> k;
        
        v.push_back(make_pair(a, k));
        v.push_back(make_pair(b+1, -1 * k));
        
    }
    
    long mx = 0, sum = 0;
    sort(v.begin(), v.end());
    
    for(int i=0; i<2*m; i++) {
    
     sum += v[i].second;
        mx = max(mx, sum);
    
    }
        
    cout << mx << endl;
    return 0;
}

2 comments:

  1. Python 3 Solution function

    def arrayManipulation(n, queries):
    summ, maxx = 0, 0
    arr = [0]*(n+1)
    for i in queries:
    a, b, k = i[0], i[1], i[2]
    arr[a-1] += k
    arr[b] -= k
    arr = arr[:n]
    for i in arr:
    summ += i
    maxx = max(summ, maxx)
    return maxx

    ReplyDelete
  2. # Ruby Solution
    # Complete the arrayManipulation function below.
    def arrayManipulation(n, queries)
    arr = Array.new(n + 1, 0)

    queries.each do |a, b, k|
    arr[a - 1] += k
    arr[b] -= k

    # arr[(a - 1), (b - a + 1)] = (a..b).map { |inx| arr[inx - 1] + k }
    # (b - a + 1).times do |inx|
    # arr[a - 1 + inx] += k
    # end
    end

    max, sum = 0, 0
    arr.each do |n|
    sum += n
    max = [sum, max].max
    end

    max
    end

    ReplyDelete

Powered by Blogger.