Arranging Coins
EasyPrompt
You have n coins and you want to build a staircase with these coins. The staircase consists of k rows where the ith row has exactly i coins. The last row of the staircase may be incomplete.
Given the integer n, return the number of complete rows of the staircase you will build.
Example 1:
Input: n = 5
Output: 2
Explanation: Because the 3rd row is incomplete, we return 2.Example 2:
Input: n = 8
Output: 3
Explanation: Because the 4th row is incomplete, we return 3.
Constraints:
1 <= n <= 231 - 1
Approaches
3 approaches with complexity analysis and trade-offs.
A more efficient approach is to use binary search. We know that the number of coins required for k complete rows is 1 + 2 + ... + k = k * (k + 1) / 2. This is a monotonically increasing function of k. We can use binary search to find the largest k for which this sum is less than or equal to n.
Algorithm
-
- Initialize
left = 1,right = n, andresult = 0.
- Initialize
-
- While
left <= right:
- While
-
- Calculate
mid = left + (right - left) / 2. Uselongto prevent overflow.
- Calculate
-
- Calculate the coins needed for
midrows:coinsNeeded = mid * (mid + 1) / 2.
- Calculate the coins needed for
-
- If
coinsNeeded <= n:
midis a potential answer. Store it:result = mid.- Search for a larger
k:left = mid + 1.
- If
-
- Else (
coinsNeeded > n):
midis too large. Search for a smallerk:right = mid - 1.
- Else (
-
- Return
result.
- Return
Walkthrough
The problem asks for the largest integer k such that the sum of coins S_k = k * (k + 1) / 2 does not exceed n. Since S_k increases as k increases, we can efficiently search for k in the range [1, n]. We set up a binary search with left and right pointers. For each mid value, we calculate the coins needed, mid * (mid + 1) / 2. If the coins needed are less than or equal to n, it means mid could be our answer, and we should try for a larger k. So, we record mid and move our search to the right half (left = mid + 1). If the coins needed are more than n, mid is too large, and we must search in the left half (right = mid - 1). It's crucial to use long for intermediate calculations to avoid integer overflow, as n can be large.
class Solution { public int arrangeCoins(int n) { long left = 1, right = n; long result = 0; while (left <= right) { long mid = left + (right - left) / 2; long coinsNeeded = mid * (mid + 1) / 2; if (coinsNeeded <= n) { result = mid; left = mid + 1; } else { right = mid - 1; } } return (int) result; }}Complexity
Time
O(log n). The binary search algorithm halves the search space in each iteration. The search space is from 1 to `n`.
Space
O(1). We only use a constant number of variables for the binary search pointers and result.
Trade-offs
Pros
Significantly faster than the brute-force approach.
Guaranteed to find the solution within logarithmic time.
Cons
Slightly more complex to implement than the linear scan.
Requires careful handling of potential integer overflows by using
long.
Solutions
Solution
class Solution { public int arrangeCoins ( int n ) { return ( int ) ( Math . sqrt ( 2 ) * Math . sqrt ( n + 0.125 ) - 0.5 ); } }Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.