跳至主要內容

1185. 一周中的第几天


1185. 一周中的第几天

🟢   🔖  数学  🔗 力扣open in new window LeetCodeopen in new window

题目

Given a date, return the corresponding day of the week for that date.

The input is given as three integers representing the day, month and year respectively.

Return the answer as one of the following values {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}.

Example 1:

Input: day = 31, month = 8, year = 2019

Output: "Saturday"

Example 2:

Input: day = 18, month = 7, year = 1999

Output: "Sunday"

Example 3:

Input: day = 15, month = 8, year = 1993

Output: "Sunday"

Constraints:

  • The given dates are valid dates between the years 1971 and 2100.

题目大意

给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。

输入为三个整数:daymonthyear,分别表示日、月、年。

您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}

示例 1:

输入: day = 31, month = 8, year = 2019

输出: "Saturday"

示例 2:

输入: day = 18, month = 7, year = 1999

输出: "Sunday"

示例 3:

输入: day = 15, month = 8, year = 1993

输出: "Sunday"

提示:

  • 给出的日期一定是在 19712100 年之间的有效日期。

解题思路

这道题的核心是判断给定的日期(由 daymonthyear 组成)对应的是星期几。

可以使用 Zeller's Congruence 算法来计算一个日期是星期几。Zeller's Congruence 是一种计算星期几的数学公式,它可以直接通过给定的日期计算出星期几的索引。

对于日期 day, month, year(假设为公历日期),Zeller's Congruence 公式如下:

h = (day + [13 * (month + 1)/5] + year + [year/4] - [year/100] + [year/400]) mod 7

其中:

  • day 是日期(1 到 31)。
  • month 是月份(1 到 12),如果是 1 月或 2 月,则视为前一年的 13 月和 14 月。
  • year 是年份。

公式计算结果 h 对应的星期几如下:

  • 0 -> Saturday
  • 1 -> Sunday
  • 2 -> Monday
  • 3 -> Tuesday
  • 4 -> Wednesday
  • 5 -> Thursday
  • 6 -> Friday
  1. 月份调整: 如果月份小于 3(即 1 月或 2 月),我们将其视为 13 月或 14 月,并将年份减去 1。
  2. 应用 Zeller's Congruence: 使用 Zeller's Congruence 公式计算出 h,它是一个整数,表示星期几。
  3. 映射星期几: 根据计算得到的 h,返回对应的星期几名称。

复杂度分析

  • 时间复杂度O(1),公式的计算只涉及常数时间操作。
  • 空间复杂度O(1),只使用了常数的空间来存储数组和中间变量。

代码

/**
 * @param {numberday
 * @param {numbermonth
 * @param {numberyear
 * @return {string}
 */
var dayOfTheWeek = function (day, month, year) {
	// Zeller's Congruence算法调整
	if (month < 3) {
		month += 12; // 把1月和2月调整为13月和14月
		year -= 1; // 年份减去1
	}

	// Zeller's Congruence公式
	let h =
		(day +
			Math.floor((13 * (month + 1)) / 5) +
			year +
			Math.floor(year / 4) -
			Math.floor(year / 100) +
			Math.floor(year / 400)) %
		7;

	// 星期几映射
	const daysOfWeek = [
		'Saturday',
		'Sunday',
		'Monday',
		'Tuesday',
		'Wednesday',
		'Thursday',
		'Friday'
	];

	return daysOfWeek[h];
};