Given a date specified by three integers day
, month
, and year
, return the corresponding day of the week as a string. The returned value should be one of: "Sunday"
, "Monday"
, "Tuesday"
, "Wednesday"
, "Thursday"
, "Friday"
, or "Saturday"
.
The input guarantees that the date is valid according to the Gregorian calendar (the calendar system in common use today). The problem assumes all dates are after 1971.
Constraints:
day
, month
, and year
together represent a valid date.At first glance, this problem seems to require determining which day of the week a particular date falls on. While you could try to simulate the passage of days from a known "anchor" date, this would be slow and error-prone, especially for dates far in the future or past.
A brute-force approach might involve counting days from a fixed starting point (like January 1, 1971) and incrementing a counter, but this is inefficient and can be tricky due to leap years and different month lengths.
Instead, we can use a well-known algorithm or built-in library to calculate the day of the week directly. Many programming languages have date libraries that handle this, but it's also possible to use formulas like Zeller's Congruence or the Doomsday algorithm.
The key is to convert the given date to a weekday index (0-6), then map that to the correct weekday name.
There are two main approaches:
For most Leetcode submissions, the first approach (using built-in libraries) is acceptable and concise. Here's the step-by-step approach:
day
, month
, and year
into a date object (or use them directly in the formula).If using Zeller's Congruence:
Example: day = 31
, month = 8
, year = 2019
"Saturday"
.Step-by-step using Zeller's Congruence:
q = 31
(day), m = 8
(month), y = 2019
(year).h = (q + [13(m+1)/5] + K + [K/4] + [J/4] + 5J) % 7
K = year % 100
, J = year // 100
.
K = 19
, J = 20
0=Saturday, 1=Sunday, ...
)."Saturday"
.Brute-force approach: If you were to count days from an anchor date, the time complexity would be O(N), where N is the number of days between the anchor and the target date. This is inefficient for dates far apart.
Optimized approach (using built-in libraries or Zeller's Congruence): Both have O(1) time and O(1) space complexity, since the calculation involves only a fixed number of arithmetic operations or a simple lookup.
The problem can be solved efficiently by leveraging either standard date libraries or a mathematical formula like Zeller's Congruence. Both approaches yield the day of the week in constant time and space. The elegance of the solution comes from recognizing that we do not need to simulate every day, but can instead use a direct computation or reliable library call.
import datetime
class Solution:
def dayOfTheWeek(self, day: int, month: int, year: int) -> str:
days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
d = datetime.date(year, month, day)
# weekday() returns 0 for Monday
return days[d.weekday()]
class Solution {
public:
string dayOfTheWeek(int day, int month, int year) {
vector<string> days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// Zeller's Congruence
if (month < 3) {
month += 12;
year -= 1;
}
int K = year % 100;
int J = year / 100;
int h = (day + 13 * (month + 1) / 5 + K + K/4 + J/4 + 5*J) % 7;
return days[h];
}
};
class Solution {
public String dayOfTheWeek(int day, int month, int year) {
String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// Zeller's Congruence
if (month < 3) {
month += 12;
year -= 1;
}
int K = year % 100;
int J = year / 100;
int h = (day + 13 * (month + 1) / 5 + K + K/4 + J/4 + 5*J) % 7;
return days[h];
}
}
var dayOfTheWeek = function(day, month, year) {
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
// JavaScript Date: month is 0-based
let d = new Date(year, month - 1, day);
return days[d.getDay()];
};