Easy
题目描述
给定一个日期,返回该日期是一周中的第几天。
输入为三个整数,分别表示日、月、年。
返回答案为以下值之一:{“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”}。
注意:1971年1月1日是星期五。
示例 1:
输入:day = 31, month = 8, year = 2019
输出:"Saturday"
示例 2:
输入:day = 18, month = 7, year = 1999
输出:"Sunday"
示例 3:
输入:day = 15, month = 8, year = 1993
输出:"Sunday"
约束条件:
- 给定的日期是1971年到2100年之间的有效日期。
提示:
- 计算给定年份之前所有年份的天数总和
- 处理闰年的情况
- 计算给定年份中每个月的天数
解题思路
这道题需要计算从1971年1月1日(星期五)到给定日期之间经过了多少天,然后通过模7运算确定星期几。
主要思路:
- 累加年份天数:计算从1971年到给定年份前一年的所有天数
- 处理闰年:需要正确判断闰年(能被4整除但不能被100整除,或能被400整除)
- 累加月份天数:计算给定年份中从1月到给定月份前一个月的所有天数
- 加上当前天数:加上给定的日期
- 模7运算:由于1971年1月1日是星期五(索引为5),最终结果需要加5再模7
优化方法:
- 可以使用数学公式(如蔡勒公式)直接计算,但累加方法更直观易懂
- 预先定义每月天数数组,简化代码
这种方法时间复杂度为O(年份差值),对于题目给定范围完全够用。
代码实现
class Solution {
public:
string dayOfTheWeek(int day, int month, int year) {
vector<string> days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
vector<int> monthDays = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int totalDays = 0;
// 计算从1971年到year-1年的总天数
for (int y = 1971; y < year; y++) {
if (isLeapYear(y)) {
totalDays += 366;
} else {
totalDays += 365;
}
}
// 计算当前年份从1月到month-1月的总天数
for (int m = 1; m < month; m++) {
totalDays += monthDays[m];
if (m == 2 && isLeapYear(year)) {
totalDays += 1;
}
}
// 加上当前月份的天数
totalDays += day - 1;
// 1971年1月1日是星期五(索引5)
return days[(totalDays + 5) % 7];
}
private:
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
};
class Solution:
def dayOfTheWeek(self, day: int, month: int, year: int) -> str:
days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
month_days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def is_leap_year(y):
return (y % 4 == 0 and y % 100 != 0) or (y % 400 == 0)
total_days = 0
# 计算从1971年到year-1年的总天数
for y in range(1971, year):
if is_leap_year(y):
total_days += 366
else:
total_days += 365
# 计算当前年份从1月到month-1月的总天数
for m in range(1, month):
total_days += month_days[m]
if m == 2 and is_leap_year(year):
total_days += 1
# 加上当前月份的天数
total_days += day - 1
# 1971年1月1日是星期五(索引5)
return days[(total_days + 5) % 7]
public class Solution {
public string DayOfTheWeek(int day, int month, int year) {
string[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int[] monthDays = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int totalDays = 0;
// 计算从1971年到year-1年的总天数
for (int y = 1971; y < year; y++) {
if (IsLeapYear(y)) {
totalDays += 366;
} else {
totalDays += 365;
}
}
// 计算当前年份从1月到month-1月的总天数
for (int m = 1; m < month; m++) {
totalDays += monthDays[m];
if (m == 2 && IsLeapYear(year)) {
totalDays += 1;
}
}
// 加上当前月份的天数
totalDays += day - 1;
// 1971年1月1日是星期五(索引5)
return days[(totalDays + 5) % 7];
}
private bool IsLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
}
var dayOfTheWeek = function(day, month, year) {
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const date = new Date(year, month - 1, day);
return days[date.getDay()];
};
复杂度分析
| 复杂度类型 | 大小 | 说明 |
|---|---|---|
| 时间复杂度 | O(year - 1971) | 需要遍历从1971年到给定年份的所有年份 |
| 空间复杂度 | O(1) | 只使用常量额外空间 |