这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战
题目
给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。
输入为三个整数:day、month 和 year,分别表示日、月、年。
您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}。
示例
输入: day = 31, month = 8, year = 2019
输出: "Saturday"
输入: day = 18, month = 7, year = 1999
输出: "Sunday"
输入: day = 15, month = 8, year = 1993
输出: "Sunday"
提示
- 给出的日期一定是在
1971到2100年之间的有效日期。
题解思路
常规的解法,是计算累加直至当天日期的所有天数,再将其取余求的当前日期为星期几。
- 计算【1971 ~ year】年的数量 * 365,再加上1971到当前年份之间的闰年数量即可得到前面的天数总和,由于1971不是闰年,所以我们需要往前推导,找到前一个闰年的下一年,这样计算的结果才准确。(1971 / 4 = 492.75,为第三年,那么我们需要往前推两年,求的结果为1969)
- 计算【1 ~ month】月的数量对应的天数。
- 最后将年份累加天数加上月份累加天数加上当前日期即可得出最终的天数总和,这里有一点需要注意的就是1971年1月1日是周五,由于我们前面年份的计算是将其当成周一来计算的,所以这里要加多三天。
代码实现
模拟
class Solution {
public String dayOfTheWeek(int day, int month, int year) {
// 计算年份累加天数
int days = 365 * (year - 1971) + (year - 1969) / 4;
// 每个月份的对应天数
int[] months = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 判断如果是闰年,则2月份需要加1天
if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)){
++months[1];
}
// 累加月份对应天数
for(int i = 0; i < month - 1; ++i){
days += months[i];
}
String[] week = new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
// 返回结果
return week[(days + day + 3) % 7];
}
}
基姆拉尔森
对于星期的计算,有一个数学公司可以快速的求的结果,那就是基姆拉尔森公式.
具体的公式原理大家可以看下这篇文章的回答,还是挺详细的。
class Solution {
public String dayOfTheWeek(int day, int month, int year) {
String[] week = new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
if(month < 3){
month += 12;
--year;
}
return week[(day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7];
}
}