文章目录
- Tag
- 题目来源
- 解题思路
- 方法一:模拟
- 写在最后
Tag
【模拟】【数学】【2023-12-30】
题目来源
1185. 一周中的第几天
解题思路
方法一:模拟
思路
题目中的日期是在 1971
到 2100
年之间的有效日期,即 1971-01-01
到 2100-12-31
范围内的任意日期。我们需要选定一个标准,将题目中给的日期和这个标准比较来得到给定的日期是一周中的周几。
这个比较的标准选择为 1970-12-31
。
比较首先需要计算给定的日期距离 1970-12-31
的天数 days
,分三部分来计算:
- 给定的年
year
距离1970
的年数对天数的贡献,注意每四年就会有闰年出现; - 给定的月份之前的月份对天数的贡献,这部分也要考虑闰年对天数的影响;
- 给定的月份中的天数贡献。
为了方便根据 days
来索引,建立一个数组 weeks = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
,最后返回 weeks[(day % 7 + 3) % 7]
即可。
算法
在具体实现中,需要判断给定的年份是不是闰年,有以下函数进行判断:
bool isLeapYear(int year) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
return false;
}
return true;
}
提交代码
class Solution {
public:
string dayOfTheWeek(int day, int month, int year) {
vector<string> weeks{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
vector<int> months{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// year 之前的整年的贡献天数
int days = (year - 1971) * 365 + (year - 1969) / 4; // 这个1969就很妙
// year年月份的贡献天数
for(int i = 1; i < month; ++i){
days += months[i];
}
// year 对 day 的贡献天数
if ((year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) && month >= 3) {
days += 1;
}
days += day;
return weeks[(days % 7 + 3) % 7]; // (days % 7 + 3) % 7 化简之后为 (days + 3) % 7
}
};
复杂度分析
时间复杂度: O ( C ) O(C) O(C),其中 C C C 为一年中的月份数 12。仅需常量时间的数学计算。
空间复杂度: O ( C ) O(C) O(C),其中 C C C 为一年中的月份数 12。仅需常量时间的数学计算。
写在最后
如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。
最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。