难度 :简单
题目大意:
给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。
输入为三个整数:
day
、month
和year
,分别表示日、月、年。您返回的结果必须是这几个值中的一个
{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
。给出的日期一定是在
1971
到2100
年之间的有效日期
题目没有给出一个标准,所以我们可以以当前时间为基准(2023, 12, 30,星期六
),但是为了处理方便,我们可以利用leetcode
上的测评特性(会直接给出答案),随便给一个返回值,测出1971,1,1
的日期,也就是星期五
,那么我们只需要知道给定的日期和这个基准时间查了多少就知道那天是星期几了,情况还是挺多的,一个一个分类来讨论,一步一步优化即可
分类讨论
class Solution {
public:
string week[7] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday",};
int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool isLeap(int year) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) return true;
return false;
}
string dayOfTheWeek(int day, int month, int year) {
int now = 4; //星期5
int d = day - 1;
month --;
while (month) {
if (isLeap(year) && month == 2) d += 1;
d += days[month-- - 1];
}
year --;
while (year >= 1971) {
if (isLeap(year--)) d += 366;
else d += 365;
}
return week[(now + d) % 7];
}
};
我们可以利用库中自带的结构体struct tm
中的int tm_wday
struct tm {
int tm_sec; /* 秒 – 取值区间为[0,59] */
int tm_min; /* 分 - 取值区间为[0,59] */
int tm_hour; /* 时 - 取值区间为[0,23] */
int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */
int tm_mon; /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */
int tm_year; /* 年份,其值等于实际年份减去1900 */
int tm_wday; /* 星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
int tm_yday; /* 从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况 时,tm_isdst()为负。*/
};
C 库函数 time_t mktime(struct tm *timeptr) 把 timeptr 所指向的结构转换为自 1970 年 1 月 1 日以来持续时间的秒数,发生错误时返回-1
C 库函数 struct tm localtime(const time_t *timer) 使用 timer 的值来填充 tm 结构。timer 的值被分解为 tm 结构,并用本地时区表示。
class Solution {
const string weekdays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
public:
string dayOfTheWeek(int day, int month, int year) {
struct tm ti = {0, 0, 0, day, month - 1, year - 1900};
time_t t = mktime(&ti);
return weekdays[localtime(&t)->tm_wday];
}
};
时间复杂度: O ( 1 ) O(1) O(1)
结束了