Day of the Week
Intuition
The cleanest way to think about this problem is:
- count how many days have passed since
January 1, 1971 - remember that
January 1, 1971was aFriday - use modulo
7to map the total back to the correct weekday
Once we reduce the question to "how many days passed before this date?", the rest becomes simple bookkeeping.
Approach
We keep two precomputed arrays:
years[i]stores how many days have passed from1971to1971 + imonths[i]stores how many days have passed before monthi + 1in a normal year
Then we build the answer in four steps:
- Add the days contributed by full years before
year - Add the days contributed by full months before
month - Add the current
day - If the year is a leap year and the month is after February, add one extra day
At that point we know the total offset from the reference Friday, so the answer is:
days[(totalDays - 1) % 7]
Code Solution
Switch between languages
class Solution {
public String dayOfTheWeek(int day, int month, int year) {
int[] years = {0,365,731,1096,1461,1826,2192,2557,2922,3287,3653,4018,4383,4748,5114,5479,5844,6209,6575,6940,7305,7670,8036,8401,8766,9131,9497,9862,10227,10592,10958,11323,11688,12053,12419,12784,13149,13514,13880,14245,14610,14975,15341,15706,16071,16436,16802,17167,17532,17897,18263,18628,18993,19358,19724,20089,20454,20819,21185,21550,21915,22280,22646,23011,23376,23741,24107,24472,24837,25202,25568,25933,26298,26663,27029,27394,27759,28124,28490,28855,29220,29585,29951,30316,30681,31046,31412,31777,32142,32507,32873,33238,33603,33968,34334,34699,35064,35429,35795,36160,36525,36890,37256,37621,37986,38351,38717,39082,39447,39812,40178,40543,40908,41273,41639,42004,42369,42734,43100,43465,43830,44195,44561,44926,45291,45656,46022,46387,46752,47117};
int[] months = {0,31,59,90,120,151,181,212,243,273,304,334,365};
String[] days = {"Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"};
int totalDays = 0;
totalDays += years[year - 1971];
totalDays += months[month - 1];
if (isLeap(year) && month > 2) {
totalDays++;
}
totalDays += day;
return days[(totalDays - 1) % 7];
}
private boolean isLeap(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
}Leap Year Rule
A year is a leap year if:
- it is divisible by
4and not divisible by100, or - it is divisible by
400
That is why 2000 is a leap year, but 1900 is not.
Dry Run
Take:
day = 31
month = 8
year = 2019
Now compute:
- days from full years before
2019 - days from months before August
- add
31 2019is not a leap year, so no extra day
After taking modulo 7, we land on Saturday.
Complexity
Time Complexity: O(1)
Space Complexity: O(1)
Why This Works Well
This solution avoids simulating calendars month by month or year by year.
Once the reference date is fixed, the whole problem becomes a direct index calculation. That makes it fast, easy to reason about, and very reliable during interviews.