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

LeetCode Problem 1344

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 * minutes degrees from the 12 o'clock position.
  • The hour hand moves 30 * hour + 0.5 * minutes degrees from the 12 o'clock position (0.5 * minutes accounts 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

  1. 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.
  2. 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.
  3. Compute the absolute difference between the two angles: angle_diff = abs(hour_angle - minute_angle).
  4. 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