• + 0 comments

    My approach to solve in O(n) was to iterate through each i student's extra time and in another array, keep track of the range of where the teacher could start grading in which student i would have enough time to complete their drawing. Ranges should be able to overlap. The result gives us an array with overlapping ranges of starting points, and the value indicated in each index of the array should be equivalent to the number of drawings that would be finished if the teacher were to start there.

    To calculate the range: We know that if given the maximum amount of extra time, the student will finish (unless t[i] == t.length, because the last student graded will only have t.length - 1 time to finish), so the range starts at i + 1, because that's a starting point where the student i will be graded last. The range continues up until the starting point where student i is graded with just the exact amount of extra time they need. Subtracting t[i] from i gives you the last spot in the range that a starting point would work. Since the students are in a circle, mod it by t.length to account for looping.

    To keep track of the ranges, instead of incrementing every value in between the start and end of the range (this would be very time- consuming with very large numbers of students), you can also just increment the value at the start of the range and decrement the same value at the index after the end of the range. This way, when iterating through the range array, you will know at what point you've entered or left the range, and if you keep track of the largest sum, it is effectively going to be the maximum value of overlapping ranges.

    Here's my solution in typescript: *note: Typescript mod operator is not a standard mod operation so I actually wrote up a method to perform what one would normally expect from mod, but for brevity I wrote this code up pretending that % works as expected

    solve(t[ ]: number[ ]) {
    		let currentId = 0;
        let max = Number.MIN_SAFE_INTEGER;
    		
    		// create an array of size t and make each index start at 0
        let ranges = Array<number>(t.length).fill(0);
        
    		// iterate through students and mark ranges in which the teacher gives enough time for that student to finish
        for (let i = 0; i<t.length; i++) {
            let startRange = i+1;
            let endRange = ((i - t[i]) % t.length) + 1;
            ranges[startRange]++;
            ranges[endRange]--;
        }
    		
    		// find the first student with largest overlapping of ranges
        let sum = 0;
        for (let i = 0; i<ranges.length; i++) {
            sum += ranges[i];
            if (sum > max) {
                max = sum;
                currentId = i;
    		}
        }
        return currentId+1
    		};