LeetCode.1185-一周中的星期幾(Day of the Week)


這是小川的第415次更新,第448篇原創

看題和准備

今天介紹的是LeetCode算法題中Easy級別的第266題(順位題號是1185)。給定日期,返回該日期的星期幾。輸入為三個整數,分別代表日,月和年。

以下列值之一返回答案:{"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年之間的有效日期。

第一種解法

題目要求我們計算給定日期是星期幾,直接調用Calendar類的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年距離當前年份的前一年總共有多少天,平年加365天,閏年加366天。

第二步,再計算給的月份的前幾個月的天數之和,閏年2月有29天。

第三步,再加上給的天數減去1天,因為題目給的示例中星期天是第一天。

第四步,將最后得到的天數再加上5天,因為1971年1月1日是星期五,然后對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];
}

第三種解法

利用蔡勒公式來解。

w =  (c/4- 2*c + y + y/4 + 26*(m + 1)/10 + d - 1) % 7;
  • c:代表世紀,是年份的前兩位,比如1971,c就為19。

  • y:是年份的后兩位,比如1971,y就是71。

  • m:代表月,3<= m <= 14,某年的1、2月要看作上一年的13、14月來計算,比如2003年1月1日,要看作2002年的13月1日來計算。

  • d:代表日。

  • w:計算結果,代表星期幾。

有一點需要注意,利用蔡勒公式算出來的數,有可能為負數,因此需要加上7,再取余一次,才能當作索引去字符串數組里取值。

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; // 世紀,年份前兩位
    int K = year % 100; // 年份,年份后兩位
    int h = (K + K / 4 + J / 4 - 2 * J +
             26 * (month + 1) / 10 + day - 1) % 7;
    // h算出來可能為負數,需要補7后再取一次余
    return week[(h + 7) % 7];
}

第四種解法

利用基姆拉爾森公式來計算。

Week = (Day + 2*Month + 3*(Month+1)/5 + Year + Year/4 - Year/100 + Year/400) % 7;

如果月份小於3月,則月份加12,年份減1。對於星期幾,在基姆拉爾森公式里,星期一是排在第一位,星期天排在最后一位。

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];
}

小結

算法專題目前已更新LeetCode算法題文章272+篇,公眾號對話框回復【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什么好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、在看就是對我最大的回報和支持!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM