Problem overview
HasPassed(int[] grades) receives a student's grades and returns true when the average is 5 or more, and false otherwise. The average is the sum of the grades divided by how many there are.
For [4, 7, 5, 9, 8, 2] the sum is 35 and there are 6 grades, so the average is 35 / 6, about 5.83. That is at least 5, so the answer is true. For [4, 7, 5, 3, 8, 2] the sum is 29 and the average is about 4.83, so the answer is false.
Approach
The problem splits into three small jobs, and each one is a line or two of code:
- Add up all the grades.
- Divide the sum by the number of grades to get the average.
- Compare the average with 5 and return the answer.
Adding up an array needs a running total and a loop that visits each element once. That makes the whole method one pass over the array, which is O(n) time with a handful of variables.
Step by step
- Declare
sumas afloatstarting at 0. It collects the total. Making it a floating-point type matters for the next division, as explained below. - Loop with
foreach.foreach (int grade in grades)hands you each grade in turn. You don't need an index, because only the values matter. - Add each grade to
sum.sum += gradedoes it. Anintconverts tofloatautomatically, so no cast is needed. - Compute the average. Declare a
floatnamedaverageand set it tosum / grades.Length. The array's size is itsLengthproperty: capital L, no parentheses. - Return the comparison.
average >= 5is already abool, so return it directly instead of writing anifthat returnstrueorfalse.
The solution in C#
class Solution {
public bool HasPassed(int[] grades) {
float sum = 0;
foreach (int grade in grades) {
sum += grade;
}
float average = sum / grades.Length;
return average >= 5;
}
}
Some C# details are worth a closer look:
- Integer division truncates. When both operands are
int, C# divides and throws away the fractional part:9 / 2is4, not 4.5. In this lesson the sum is afloat, sosum / grades.Lengthis a floating-point division and the fraction is kept. For the second example, the result is about 4.8333335. - The result is a
float. When one operand is afloatand the other anint, C# converts theintand divides as floats. That is whygrades.Lengthneeds no cast here. foreachreads, it doesn't write. The loop variablegradeis a copy of each element and can't be assigned to. That is fine here, since the loop only reads.floathas limited precision. It keeps about 7 significant digits, so very large integer sums can't all be represented exactly. For grades this is irrelevant. When precision matters,doubleis the usual choice.
A useful observation: because the pass mark is a whole number and grades are integers, the test sum >= 5 * grades.Length gives the same answer without any division. Truncating integer division would also give the same true or false here, since cutting off a fraction never moves a value across a whole number boundary. The lesson uses float because it shows what the average really is, and because the habit matters in the many problems where the fraction does count.
Complexity
Time: O(n), where n is the number of grades. The loop touches each grade once, and the division and comparison happen once.
Space: O(1). The method keeps sum, average and the loop variable, whatever the array size.
Edge cases and common mistakes
- Exactly 5. The comparison is
>=, so an average of exactly 5, as in[5, 5]or[3, 7], passes. Using>would be a bug. - An empty array. Here
grades.Lengthis 0. With afloatsum, 0 / 0 givesNaN("not a number") and every comparison withNaNis false, so the method returnsfalsewithout crashing. With anintsum, the same division throws aDivideByZeroException. If an empty array can reach your code, handle it explicitly. - Forgetting the division. Comparing
sumitself with 5 passes almost everyone. The sum has to be divided by the count first. - Dividing by the wrong number. Using the largest index (
Length - 1) instead ofLengthgives a wrong average. - Declaring
suminside the loop. It would reset on every pass. Declare it before the loop.
Testing
[4, 7, 5, 9, 8, 2]givestrue.[4, 7, 5, 3, 8, 2]givesfalse.[5]givestrue, because the average is exactly 5.[4]givesfalse.[10, 0]givestrue, since the average is exactly 5.