简体   繁体   中英

Algorithm: count the number of the requests

Requests for a system are routed through a bus to ensure and the bus has the limits.

I write the solution provided below.

class App {

public static int solution(List<Integer> values) {

        int[] A = getRequestFrequency(values);

        int count = 0;
        int N = A.length;

        int[] offsets = {10, 60};
        int[] limits = {20, 60};


        for (int i = 0; i < N; i++) {

            if (A[i] > 3) {
                count += A[i] - 3;
            }

            int k = i;
            int temp = 0;

            while (k < N && i + 10 > k) {

                temp += A[k];
                k++;
            }

            if (temp > 20) {
                count += temp - 20;
            }


            k = i;
            temp = 0;

            while (k < N && i + 60 > k) {
                temp += A[k];
                k++;
            }

            if (temp > 60) {
                count += temp - 60;
            }
        }

        return count;
    }

    public static int[] getRequestFrequency(List<Integer> requestTime) {

        int lastElement = requestTime.get(requestTime.size() - 1);

        int[] result = new int[lastElement];

        Map<Integer, Integer> map = new TreeMap<>();

        for (int key : requestTime) {

            int value = map.containsKey(key) ? map.get(key) + 1 : 1;
            map.put(key, value);
        }

        for (int i = 0; i < lastElement; i++) {

            if (map.containsKey(i + 1)) {

                result[i] = map.get(i + 1);
                continue;
            }

            result[i] = 0;
        }

        return result;
    }

    public static void main(String[] args) {

        // 67
        Integer[] A = {1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20};

//        Integer[] A = {1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 11, 11, 11};

        List<Integer> list = Arrays.asList(A);
        System.out.println(solution(list));



    }

}

What's the bug here and how to solve it?

Here is the solution that should work. Ideally you just have 2 variable that keeps the count of number of requests that has been received in the last 10 and 60 secs resp. Then you check how many requests you need to drop so that the given constraints are met.

Also you don't need to create a map for your getRequestFrequency function. It can be done with a simple loop.

public static int droppedRequests(List<Integer> requestTime) {

    int[] A = getRequestFrequency(requestTime);
    int count1 = 0;
    int last10 = 0 ;
    int last60 = 0;
    for (int i = 0; i < A.length; i++) {
        if(i-10 >= 0){
            last10 -= A[i-10];
        }
        if(i-60 >= 0){
            last60 -= A[i-60];
        }
        last10 += A[i];
        last60 += A[i];
        int dropped = 0;
        int rem = A[i];
        if(A[i]>3){
            dropped += A[i] - 3;
            rem -= dropped;
        }
        if(last10 > 20) {
            int toDrop = last10 - 20;
            if(rem > toDrop) {
                dropped += toDrop;
                rem -= toDrop;
            }else {
                dropped += rem;
                rem = 0;
            }
        }
        if(last60 > 60) {
            int toDrop = last60 - 60;
            if(rem > toDrop) {
                dropped += toDrop;
                rem -= toDrop;
            }else {
                dropped += rem;
                rem = 0;
            }
        }
        count1 += dropped;
        A[i] = rem;
    }
    return count1;
}

public static int[] getRequestFrequency(List<Integer> requestTime) {

    int lastElement = requestTime.get(requestTime.size() - 1);
    int[] result = new int[lastElement];
    for (Integer integer : requestTime) {
        result[integer - 1]++;
    }
    return result;
}

The following solution seems to be the correct one:
I found it in this link Throttling Gateway Hackerrank . ( @dariosicily this link also includes the Hackerrank challenge question ).

The Hackerrank challenge question:

Throttling Gateway

Non-critical requests for a transaction system are routed through a throttling gateway to ensure that the network is not choked by non-essential requests.

The gateway has the following limits:

* The number of transactions in any given second cannot exceed 3
* The number of transactions in any given 10 second period cannot exceed 20.
* The number of transactions in any given minute cannot exceed 60.

The solution:

public static int droppedRequests(List<Integer> requestTime) {

    int[] requestTimeArr = requestTime.stream().mapToInt(i->i).toArray();

    int dropped = 0;

    for (int i = 0 ; i < requestTimeArr.length ; i++) {

        if (i > 2 && requestTimeArr[i] == requestTimeArr[i-3]) {
            ++dropped;
        } else if (i > 19 && (requestTimeArr[i] - requestTimeArr[i-20]) < 10) {
            ++dropped;
        } else if (i > 59 && (requestTimeArr[i] - requestTimeArr[i-60]) < 60) {
            ++dropped;
        }
    }

    return dropped;
}

This answer seems to be correct:

static class Txn {
    public int count;
    public int dropped;

    public Txn(int count) {
        this.count = count;
    }

    public void addNewDropped(int newDropped) {
        if (this.dropped < newDropped) {
            if (newDropped > count)
                dropped = count;
            else
                dropped = newDropped;
        }
    }
}

static class ThrottleRule {
    public int window;
    public int limit;
    public int curSum = 0;

    public ThrottleRule(int window, int limit) {
        this.window = window;
        this.limit = limit;
    }
}

public static int droppedRequests(List<Integer> requestTime) {
    HashMap<Integer, Txn> hitsMap = new HashMap<Integer, Txn>(); // seconds, Txn count
    for (Integer req : requestTime) {
        Txn txn = hitsMap.get(req);
        if (txn == null)
            hitsMap.put(req, new Txn(1));
        else
            txn.count += 1;
    }

    // gateway Throttle limits rules
    ArrayList<ThrottleRule> gatewayRules = new ArrayList<ThrottleRule>();
    gatewayRules.add(new ThrottleRule(1, 3));
    gatewayRules.add(new ThrottleRule(10, 20));
    gatewayRules.add(new ThrottleRule(60, 60));

    for (ThrottleRule gw : gatewayRules) {
        for (Map.Entry<Integer, Txn> entry : hitsMap.entrySet()) {

            // entry.getKey() --> current second,
            Txn curTxn = entry.getValue();
            gw.curSum += curTxn.count;
            int lostPeriod = 0;

            while (entry.getKey() - gw.window - lostPeriod > 0) {
                Txn txn = hitsMap.get(entry.getKey() - gw.window - lostPeriod);
                if (txn != null) {
                    gw.curSum -= txn.count;
                    break;
                } else {
                    lostPeriod++;
                }
            }

            if (gw.curSum > gw.limit) {
                curTxn.addNewDropped(gw.curSum - gw.limit);
            }
        }
    }

    // summ all dropped
    int dropped = 0;
    for (Map.Entry<Integer, Txn> entry : hitsMap.entrySet()) {
        dropped += entry.getValue().dropped;
    }
    return dropped;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM