Problem overview
The method findLargestNumber(_ S: Int) takes a positive number S and returns the largest n for which 1² + 2² + 3² + ... + n² is at most S. For S = 35 the sums are 1, 5, 14 and 30 for n = 1 to 4, and adding 5² = 25 would give 55, which is more than 35. The answer is 4.
Approach
Add the squares one at a time and stop just before the sum would go over S. Two variables are enough: totalSoFar, the sum of the squares added so far, and number, the next number whose square is considered. Because every square is positive, the sum only grows, so the first square that doesn't fit ends the search for good: no larger n can work.
The loop condition looks one step ahead: totalSoFar + number * number <= S asks whether adding the next square still fits. The body then performs the addition. That way totalSoFar never exceeds S.
Step by step
- Declare
totalSoFarasvar, set to 0. Nothing has been added yet. - Declare
numberasvar, set to 1. The sum starts with 1². - Write the
whileloop with the conditiontotalSoFar + number * number <= S. - Add the square:
totalSoFar += number * number. - Increment:
number += 1. Swift has no++operator, so+= 1is the form to use. Without this line the loop would never end. - Return
number - 1. After the last successful additionnumberwas incremented once more, so it points one past the answer.
The solution in Swift
class Solution {
func findLargestNumber(_ S: Int) -> Int {
var totalSoFar = 0
var number = 1
while totalSoFar + number * number <= S {
totalSoFar += number * number
number += 1
}
return number - 1
}
}
Tracing S = 35: the checks are 0 + 1 <= 35, 1 + 4 <= 35, 5 + 9 <= 35 and 14 + 16 <= 35, all true. After the fourth pass totalSoFar is 30 and number is 5. The next check is 30 + 25 <= 35, which is false, so the loop ends and the method returns 5 - 1 = 4.
Swift details:
vardeclares a variable that can change,letone that cannot. Both counters change, so both arevar.Intis 64 bits. Arithmetic that overflows traps and crashes the program instead of wrapping around. Here the sums stay far below that limit unlessSis close to the maximumInt.- No parentheses are needed around the condition, and the braces are required.
Complexity
Time: the sum 1² + ... + n² is about n³ / 3, so the loop stops when n is roughly the cube root of 3 * S. Time is therefore O(S^(1/3)), which is much less than O(S). If you describe it by the answer n instead, it is O(n). Space: O(1), two integers.
Edge cases and common mistakes
Ssmaller than 1. WithS = 0, the first check 0 + 1 <= 0 is false, so the loop never runs and the method returns 0. No positive number fits.Sexactly equal to a sum. ForS = 30the answer is 4, because the condition uses<=. WithS = 29the answer drops to 3.- Checking after adding. If the loop adds the square first and tests the total afterwards, the last addition may already have gone over
S, and the returned value is too large. - Returning
number. It is one past the answer. ForS = 35it would return 5. - Forgetting the increment, which makes an infinite loop.
Testing
S = 35gives4.S = 30gives4.S = 29gives3.S = 1gives1.S = 0gives0.
