LeetCode 1344 - Angle Between Hands of a Clock
This problem asks us to compute the smaller angle formed between the hour hand and the minute hand on a standard 12-hour
Difficulty: 🟡 Medium
Topics: Math
Solution
Problem Understanding
This problem asks us to compute the smaller angle formed between the hour hand and the minute hand on a standard 12-hour analog clock given two integers, hour and minutes. The input hour ranges from 1 to 12 and represents the hour on the clock, while minutes ranges from 0 to 59 and represents the minute within that hour. The expected output is a floating-point number representing the smaller angle in degrees between the two hands. Answers within 10^-5 of the correct value are considered acceptable.
The problem requires understanding how both the hour hand and the minute hand move. The minute hand moves 360 degrees per 60 minutes, which corresponds to 6 degrees per minute. The hour hand moves 360 degrees per 12 hours, which corresponds to 30 degrees per hour, but it also moves continuously as the minutes progress. For example, at 3:30, the hour hand is halfway between 3 and 4, not exactly on 3.
Important edge cases include when the hour is 12 (which corresponds to 0 degrees), when minutes are 0, when the hour hand and minute hand are on the same line, or when the calculated angle exceeds 180 degrees, in which case we must return the smaller angle (less than or equal to 180 degrees). The problem guarantees that the inputs are valid integers within their ranges.
Approaches
A brute-force approach would be to simulate the positions of the hour and minute hands in a linear fashion, iterating minute by minute or degree by degree, then compute the difference. While conceptually correct, this is unnecessary and inefficient given the direct formulas for the positions of the hands.
The optimal approach leverages the fact that the positions of the hands can be calculated directly using a simple formula:
- The minute hand moves
6 * minutesdegrees from the 12 o'clock position. - The hour hand moves
30 * hour + 0.5 * minutesdegrees from the 12 o'clock position (0.5 * minutesaccounts for the hour hand’s continuous movement).
Once both angles are computed, the absolute difference gives the angle between the hands. If this difference exceeds 180 degrees, subtract it from 360 to get the smaller angle.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(360) | O(1) | Simulate each degree or each minute to compute angle |
| Optimal | O(1) | O(1) | Direct computation of angles using formulas |
Algorithm Walkthrough
- Compute the angle of the minute hand from 12 o'clock using
minute_angle = minutes * 6. This works because the minute hand moves 360 degrees in 60 minutes, so each minute corresponds to 6 degrees. - Compute the angle of the hour hand from 12 o'clock using
hour_angle = (hour % 12) * 30 + minutes * 0.5. The modulo ensures that 12 is treated as 0. Each hour contributes 30 degrees, and each minute contributes 0.5 degrees because the hour hand gradually moves between hours. - Compute the absolute difference between the two angles:
angle_diff = abs(hour_angle - minute_angle). - Return the smaller angle by taking
min(angle_diff, 360 - angle_diff). This ensures the angle is always ≤180 degrees.
Why it works: The algorithm correctly models the continuous movement of the hour and minute hands. Using direct formulas ensures O(1) time complexity, and taking the minimum of the difference and its complement guarantees the smaller angle is returned.
Python Solution
class Solution:
def angleClock(self, hour: int, minutes: int) -> float:
# Calculate the angle of the minute hand from 12 o'clock
minute_angle = minutes * 6
# Calculate the angle of the hour hand from 12 o'clock
hour_angle = (hour % 12) * 30 + minutes * 0.5
# Calculate the absolute difference between hour and minute hands
angle_diff = abs(hour_angle - minute_angle)
# Return the smaller angle
return min(angle_diff, 360 - angle_diff)
The implementation follows the algorithm directly. minute_angle and hour_angle are computed using formulas derived from the mechanical movement of clock hands. abs(hour_angle - minute_angle) ensures a non-negative difference, and min(..., 360 - ...) ensures the smaller angle is returned.
Go Solution
func angleClock(hour int, minutes int) float64 {
// Calculate the angle of the minute hand
minuteAngle := float64(minutes) * 6.0
// Calculate the angle of the hour hand
hourAngle := float64(hour%12)*30.0 + float64(minutes)*0.5
// Compute the absolute difference
diff := hourAngle - minuteAngle
if diff < 0 {
diff = -diff
}
// Return the smaller angle
if diff > 180 {
return 360 - diff
}
return diff
}
In Go, type conversion is required to handle floating-point calculations. The approach mirrors Python: calculate angles, compute absolute difference, and return the smaller angle.
Worked Examples
Example 1: hour = 12, minutes = 30
| Variable | Calculation | Value |
|---|---|---|
| minute_angle | 30 * 6 | 180 |
| hour_angle | (12 % 12) * 30 + 30 * 0.5 | 15 |
| angle_diff | abs(15 - 180) | 165 |
| result | min(165, 360-165) | 165 |
Example 2: hour = 3, minutes = 30
| Variable | Calculation | Value |
|---|---|---|
| minute_angle | 30 * 6 | 180 |
| hour_angle | 3 * 30 + 30 * 0.5 | 105 |
| angle_diff | abs(105 - 180) | 75 |
| result | min(75, 360-75) | 75 |
Example 3: hour = 3, minutes = 15
| Variable | Calculation | Value |
|---|---|---|
| minute_angle | 15 * 6 | 90 |
| hour_angle | 3 * 30 + 15 * 0.5 | 97.5 |
| angle_diff | abs(97.5 - 90) | 7.5 |
| result | min(7.5, 360-7.5) | 7.5 |
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(1) | All calculations are direct formulas, no loops or recursion |
| Space | O(1) | Only a fixed number of variables are used |
The reasoning is straightforward: there are no iterative or recursive steps that depend on input size. All computations involve basic arithmetic.
Test Cases
# Provided examples
assert Solution().angleClock(12, 30) == 165 # Hour hand at 12:30, smaller angle 165
assert Solution().angleClock(3, 30) == 75 # Hour hand at 3:30, smaller angle 75
assert Solution().angleClock(3, 15) == 7.5 # Hour hand at 3:15, smaller angle 7.5
# Boundary cases
assert Solution().angleClock(12, 0) == 0 # Both hands at 12
assert Solution().angleClock(6, 0) == 180 # Opposite hands
assert Solution().angleClock(9, 0) == 90 # Right angle
assert Solution().angleClock(1, 59) == 35.5 # Near hour rollover
# Minute edge
assert Solution().angleClock(12, 59) == 5.5 # Minute hand almost at 12
assert Solution().angleClock(11, 59) == 5.5 # Hour hand near 12
| Test | Why |
|---|---|
| 12:30 | Confirms standard case with half-hour offset |
| 3:30 | Confirms standard quarter-hour case |
| 3:15 | Confirms smaller fractional angle calculation |
| 12:0 | Both hands at top of clock |
| 6:0 | Hands opposite, 180 degrees |
| 9:0 | Right angle, standard multiple of 90 |
| 1:59 | Hour hand nearly at next hour |
| 12:59 | Minute hand almost completes hour |
| 11:59 | Edge case with hour hand near 12 |
Edge Cases
Edge Case 1: Hour is 12
When hour is 12, it corresponds to 0 degrees. Without using modulo, calculations could produce 360 degrees, causing incorrect differences. Using hour % 12 ensures the angle starts from 0 degrees.
Edge Case 2: Minutes at 0
When minutes is 0, the minute hand is exactly at 12. The hour hand may be anywhere. Properly handling this ensures the difference calculation is correct and avoids division or multiplication errors.
Edge Case 3: Angle greater than 180 degrees
The angle between the hands can exceed 180 degrees. Taking the minimum between the calculated difference and its complement ensures that the smaller angle is always returned, which is what the problem