You may notice that if A[n+1] > A[n] , we must start strokes A[n+1]-A[n] . But if A[n+1] < A[n] , we must put an end to A[n]-A[n+1] .
Since we are only interested in the number of strokes started, we could sum A[n+1]-A[n] when the condition A[n+1] > A[n] is fulfilled.
This means that we perform no more than N-1 sums, that is, O(N) .
class Program { public static int ComputeNumberOfStrokes(List<int> skyline) { const int MAX = 1000000001; var strokes = skyline.Zip(skyline.Skip(1), (a, b) => b - a) .Where(d => d > 0) .Aggregate(skyline[0], (a, b) => Math.Min(a + b, MAX)); return strokes >= MAX ? -1 : strokes; } static void Main(string[] args) { var skyline1 = new List<int> { 1, 3, 1, 3, 2, 1 }; var skyline2 = new List<int> { 1, 2, 3, 4, 3, 2, 1 }; var skyline3 = new List<int> { 1, 2, 3, 4, 1, 2, 3, 4 }; Console.WriteLine(ComputeNumberOfStrokes(skyline1)); Console.WriteLine(ComputeNumberOfStrokes(skyline2)); Console.WriteLine(ComputeNumberOfStrokes(skyline3)); Console.In.ReadLine(); } }
This will return 5 4 7 . What are the expected results.
source share