這是小川的第415次更新封恰,第448篇原創(chuàng)
看題和準(zhǔn)備
今天介紹的是LeetCode算法題中Easy級(jí)別的第266題(順位題號(hào)是1185)耘分。給定日期,返回該日期的星期幾它褪。輸入為三個(gè)整數(shù)饵骨,分別代表日,月和年茫打。
以下列值之一返回答案:{"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年之間的有效日期。
第一種解法
題目要求我們計(jì)算給定日期是星期幾老赤,直接調(diào)用Calendar類(lèi)的API轮洋,如果是面試不建議這么做。
public String dayOfTheWeek(int day, int month, int year) {
String[] week = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
Calendar cal = Calendar.getInstance();
cal.set(year, month-1, day);
int i = cal.get(Calendar.DAY_OF_WEEK)-1;
if (i<0) {
i = 0;
}
return week[i];
}
第二種解法
第一步抬旺,先算出從1971年距離當(dāng)前年份的前一年總共有多少天弊予,平年加365天,閏年加366天开财。
第二步汉柒,再計(jì)算給的月份的前幾個(gè)月的天數(shù)之和,閏年2月有29天责鳍。
第三步碾褂,再加上給的天數(shù)減去1天,因?yàn)轭}目給的示例中星期天是第一天历葛。
第四步正塌,將最后得到的天數(shù)再加上5天,因?yàn)?971年1月1日是星期五恤溶,然后對(duì)7取余乓诽。
public String dayOfTheWeek2(int day, int month, int year) {
String[] week = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
int[] dayOfMonth = {31,28,31,30,31,30,31,31,30,31,30,31};
int total = 0;
for (int i=1971; i<year; i++) {
if (i%4 == 0) {
total++;
}
total += 365;
}
if (year%4 == 0) {
dayOfMonth[1] = 29;
}
for (int j=0; j<month-1; j++) {
total += dayOfMonth[j];
}
total += day - 1;
return week[(total + 5)%7];
}
第三種解法
利用蔡勒公式來(lái)解。
w = (c/4- 2*c + y + y/4 + 26*(m + 1)/10 + d - 1) % 7;
c:代表世紀(jì)咒程,是年份的前兩位鸠天,比如1971,c就為19帐姻。
y:是年份的后兩位稠集,比如1971,y就是71卖宠。
m:代表月巍杈,3<= m <= 14,某年的1扛伍、2月要看作上一年的13筷畦、14月來(lái)計(jì)算,比如2003年1月1日,要看作2002年的13月1日來(lái)計(jì)算鳖宾。
d:代表日吼砂。
w:計(jì)算結(jié)果,代表星期幾鼎文。
有一點(diǎn)需要注意渔肩,利用蔡勒公式算出來(lái)的數(shù),有可能為負(fù)數(shù)拇惋,因此需要加上7周偎,再取余一次,才能當(dāng)作索引去字符串?dāng)?shù)組里取值撑帖。
public String dayOfTheWeek3(int day, int month, int year) {
String[] week = { "Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday", "Saturday" };
//如果月份小于3月蓉坎,則月份加12,年份減1
if (month < 3) {
month += 12;
year -= 1;
}
int J = year / 100; // 世紀(jì)胡嘿,年份前兩位
int K = year % 100; // 年份蛉艾,年份后兩位
int h = (K + K / 4 + J / 4 - 2 * J +
26 * (month + 1) / 10 + day - 1) % 7;
// h算出來(lái)可能為負(fù)數(shù),需要補(bǔ)7后再取一次余
return week[(h + 7) % 7];
}
第四種解法
利用基姆拉爾森公式來(lái)計(jì)算衷敌。
Week = (Day + 2*Month + 3*(Month+1)/5 + Year + Year/4 - Year/100 + Year/400) % 7;
如果月份小于3月勿侯,則月份加12,年份減1缴罗。對(duì)于星期幾助琐,在基姆拉爾森公式里,星期一是排在第一位瞒爬,星期天排在最后一位弓柱。
public String dayOfTheWeek4(int day, int month, int year) {
String[] week = {"Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"};
if (month < 3) {
month += 12;
year -= 1;
}
int w = (day + 2*month + 3*(month+1)/5 +
year + year/4 - year/100 + year/400) % 7;
return week[w];
}
小結(jié)
算法專(zhuān)題目前已更新LeetCode算法題文章272+篇沟堡,公眾號(hào)對(duì)話(huà)框回復(fù)【數(shù)據(jù)結(jié)構(gòu)與算法】侧但、【算法】、【數(shù)據(jù)結(jié)構(gòu)】中的任一關(guān)鍵詞航罗,獲取系列文章合集禀横。
以上就是全部?jī)?nèi)容,如果大家有什么好的解法思路粥血、建議或者其他問(wèn)題柏锄,可以下方留言交流,點(diǎn)贊复亏、留言趾娃、在看就是對(duì)我最大的回報(bào)和支持!