LeetCode 1344. 时钟指针的夹角
题目描述



题意分析
给出十二小时制的小时和分钟,计算时针与分针形成的较小夹角,以度为单位返回。答案范围是零到一百八十度,可以包含小数。
指针连续运动,时针会随着本小时已经过去的分钟继续前进,不能一直停在整点刻度。小时为十二时与零时方向相同,分钟范围为零到五十九。
解法:角度计算
核心思路
[!blue]
统一以十二点方向为零度,并沿顺时针测量两根指针的位置。分针一小时转三百六十度,六十分钟平均每分钟六度,因此
minuteAngle = 6 * minutes。时针十二小时转一圈,每小时三十度;每小时内部仍连续转动,因此每分钟再走半度。先用
hour % 12将十二点归零,得到hourAngle = 30 * (hour % 12) + 0.5 * minutes。两个方向角都在同一圈内,绝对差
diff表示沿其中一侧量出的夹角。圆周被两根指针分成两段,另一侧角度是360 - diff,取两者较小值即可;指针重合时自然得到零,相对时得到一百八十度。所有角度使用浮点计算,特别是时针每分钟前进的半度不能用整数除法截断。这里不需要模拟时间流逝,直接由转速和经过时间计算当前角度。
解题步骤
- 计算分针角度
6.0 * minutes。- 计算时针角度
30.0 * (hour % 12) + 0.5 * minutes。- 取两者绝对差
diff。- 返回
min(diff, 360.0 - diff)。
代码实现
class Solution {
public double angleClock(int hour, int minutes) {
// 分针每分钟走 360 / 60 = 6 度。
double minuteAngle = 6.0 * minutes;
// 时针每小时走 30 度,且在一小时内以 0.5 度每分钟连续推进。
double hourAngle = 30.0 * (hour % 12) + 0.5 * minutes;
// 谁在前不确定,取绝对值。
double diff = Math.abs(hourAngle - minuteAngle);
// 两段弧之和为 360,取较小的那段。
return Math.min(diff, 360.0 - diff);
}
}
import "math"
func angleClock(hour int, minutes int) float64 {
minuteAngle := 6.0 * float64(minutes)
// 时针随分钟连续前进,每分钟另加半度。
hourAngle := 30.0*float64(hour%12) + 0.5*float64(minutes)
diff := math.Abs(hourAngle - minuteAngle)
// 两个方向的夹角合为一整圈,返回较小者。
return math.Min(diff, 360.0-diff)
}
复杂度分析
- 时间复杂度:$O(1)$,固定次数的算术运算。
- 空间复杂度:$O(1)$,只保存几个角度值。
关键点总结
[!green]
- 时针每分钟前进半度,这是公式中不能漏掉的一项。
- 取绝对值处理两指针的先后关系。
- 返回较小方向,答案在 0° 到 180° 之间。
易错点总结
[!yellow]
- 时针角度只计算整点部分,会漏掉分钟造成的连续偏移。
- 用整数运算计算半度贡献,会把奇数分钟对应的小数角度截断。
- 只返回角度绝对差,可能返回大于一百八十度的较大夹角。
- 对一百八十取模不能代替比较两段圆弧,会把合法的一百八十度错误变成零。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 539. 最小时间差 | 中等 | 同样在周期坐标上求最短距离,不能只取绝对差,还要比较绕过周期边界的距离。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!