1118. Number of Days in a Month
Problem Description
Given a year and a month as input, you need to return the number of days in that specific month.
The problem requires you to handle the varying number of days in different months, with special consideration for February in leap years. A leap year occurs when:
- The year is divisible by 4 AND not divisible by 100, OR
- The year is divisible by 400
For example:
- January (month 1) always has 31 days
- February (month 2) has 29 days in a leap year and 28 days in a common year
- April (month 4) always has 30 days
The solution uses an array days
where index i
represents month i
, with days[0]
set to 0 as a placeholder. The code first determines if the given year is a leap year using the formula (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
. Based on this, it sets February's days to either 29 or 28, then returns the number of days for the requested month by accessing days[month]
.
Intuition
The key insight is that most months have a fixed number of days that never change - only February varies based on whether it's a leap year or not. This means we can pre-define the days for all months and only need to handle the special case of February.
To determine February's days, we need to identify leap years. The leap year rule follows a specific pattern: years divisible by 4 are typically leap years, but there's an exception for century years (divisible by 100) which are not leap years unless they're also divisible by 400. This gives us the formula: (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
.
Once we know if it's a leap year, we can build a simple lookup table. Using an array to store the days for each month is natural since months are numbered 1-12. We include a dummy value at index 0 so that month numbers directly correspond to array indices (month 1 maps to index 1, month 2 to index 2, etc.).
The approach avoids complex if-else statements for each month by using direct array indexing, making the solution both efficient and clean. We compute the leap year status once, adjust February's days accordingly, and then simply return the value at the corresponding index.
Learn more about Math patterns.
Solution Approach
The implementation follows a straightforward approach by first determining if the given year is a leap year, then using a lookup table to return the number of days.
Step 1: Determine Leap Year
We calculate whether the year is a leap year using the boolean expression:
leap = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
This checks two conditions:
- If the year is divisible by 4 but not by 100 (common leap years like 2020, 2024)
- If the year is divisible by 400 (century leap years like 2000, 2400)
Step 2: Build the Days Array
We create an array days
where each index represents a month:
days = [0, 31, 29 if leap else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
The array structure:
- Index 0: Set to 0 (placeholder to align month numbers with indices)
- Index 1-12: Number of days for months January through December
- February (index 2): Uses conditional expression to set 29 days if leap year, otherwise 28
The fixed days for other months are:
- 31 days: January, March, May, July, August, October, December
- 30 days: April, June, September, November
Step 3: Return the Result
Simply access the array at the given month index:
return days[month]
The time complexity is O(1)
as we perform a constant number of operations regardless of input. The space complexity is also O(1)
since the array size is fixed at 13 elements.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through two examples to illustrate how the solution works:
Example 1: February 2024
- Input: year = 2024, month = 2
- Step 1: Check if 2024 is a leap year
- Is 2024 % 4 == 0? Yes (2024 ÷ 4 = 506)
- Is 2024 % 100 == 0? Yes (2024 ÷ 100 = 20.24, not evenly divisible)
- Since 2024 is divisible by 4 but NOT by 100, it's a leap year
leap = True
- Step 2: Build the days array
days = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
- February (index 2) gets 29 days since
leap
is True
- Step 3: Return
days[2] = 29
Example 2: February 1900
- Input: year = 1900, month = 2
- Step 1: Check if 1900 is a leap year
- Is 1900 % 4 == 0? Yes (1900 ÷ 4 = 475)
- Is 1900 % 100 == 0? Yes (1900 ÷ 100 = 19)
- Is 1900 % 400 == 0? No (1900 ÷ 400 = 4.75)
- Since 1900 is divisible by 100 but NOT by 400, it's NOT a leap year
leap = False
- Step 2: Build the days array
days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
- February (index 2) gets 28 days since
leap
is False
- Step 3: Return
days[2] = 28
Example 3: April 2023
- Input: year = 2023, month = 4
- Step 1: Check if 2023 is a leap year (only matters for February)
- Is 2023 % 4 == 0? No (2023 ÷ 4 = 505.75)
leap = False
- Step 2: Build the days array
days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
- Step 3: Return
days[4] = 30
- April always has 30 days regardless of leap year status
Solution Implementation
1class Solution:
2 def numberOfDays(self, year: int, month: int) -> int:
3 """
4 Calculate the number of days in a given month of a specific year.
5
6 Args:
7 year: The year (used to determine if it's a leap year)
8 month: The month (1-12)
9
10 Returns:
11 The number of days in the specified month
12 """
13 # Check if the year is a leap year
14 # A year is a leap year if:
15 # 1. It's divisible by 4 AND not divisible by 100, OR
16 # 2. It's divisible by 400
17 is_leap_year = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
18
19 # Days in each month (index 0 is placeholder, months are 1-indexed)
20 # February has 29 days in leap years, 28 otherwise
21 days_in_month = [
22 0, # Placeholder for index 0
23 31, # January
24 29 if is_leap_year else 28, # February
25 31, # March
26 30, # April
27 31, # May
28 30, # June
29 31, # July
30 31, # August
31 30, # September
32 31, # October
33 30, # November
34 31 # December
35 ]
36
37 # Return the number of days for the requested month
38 return days_in_month[month]
39
1class Solution {
2 /**
3 * Returns the number of days in a given month of a given year.
4 * Takes into account leap years for February.
5 *
6 * @param year The year (e.g., 2024)
7 * @param month The month (1-12, where 1 is January and 12 is December)
8 * @return The number of days in the specified month
9 */
10 public int numberOfDays(int year, int month) {
11 // Check if the year is a leap year
12 // A leap year is divisible by 4, except for years divisible by 100
13 // unless they are also divisible by 400
14 boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
15
16 // Array storing the number of days for each month
17 // Index 0 is unused (placeholder), indices 1-12 correspond to months January-December
18 int[] daysInMonth = new int[] {
19 0, // Index 0: placeholder
20 31, // January
21 isLeapYear ? 29 : 28, // February (29 days in leap year, 28 otherwise)
22 31, // March
23 30, // April
24 31, // May
25 30, // June
26 31, // July
27 31, // August
28 30, // September
29 31, // October
30 30, // November
31 31 // December
32 };
33
34 // Return the number of days for the specified month
35 return daysInMonth[month];
36 }
37}
38
1class Solution {
2public:
3 /**
4 * Calculate the number of days in a given month of a specific year
5 * @param year - The year (used to determine if it's a leap year)
6 * @param month - The month (1-12)
7 * @return The number of days in the specified month
8 */
9 int numberOfDays(int year, int month) {
10 // Determine if the year is a leap year
11 // A leap year is divisible by 4 but not by 100, unless it's also divisible by 400
12 bool isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
13
14 // Days in each month (index 0 is unused, months are 1-indexed)
15 // February has 29 days in a leap year, 28 otherwise
16 vector<int> daysInMonth = {
17 0, // Index 0 (unused)
18 31, // January
19 isLeapYear ? 29 : 28, // February
20 31, // March
21 30, // April
22 31, // May
23 30, // June
24 31, // July
25 31, // August
26 30, // September
27 31, // October
28 30, // November
29 31 // December
30 };
31
32 // Return the number of days for the given month
33 return daysInMonth[month];
34 }
35};
36
1/**
2 * Calculates the number of days in a given month of a specific year
3 * @param year - The year (used to determine if it's a leap year)
4 * @param month - The month (1-12, where 1 is January and 12 is December)
5 * @returns The number of days in the specified month
6 */
7function numberOfDays(year: number, month: number): number {
8 // Determine if the year is a leap year
9 // A leap year occurs every 4 years, except for years divisible by 100
10 // However, years divisible by 400 are still leap years
11 const isLeapYear: boolean = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
12
13 // Array containing the number of days for each month
14 // Index 0 is unused (placeholder), indices 1-12 represent January-December
15 // February (index 2) has 29 days in leap years, 28 otherwise
16 const daysInMonth: number[] = [
17 0, // Placeholder for index 0
18 31, // January
19 isLeapYear ? 29 : 28, // February
20 31, // March
21 30, // April
22 31, // May
23 30, // June
24 31, // July
25 31, // August
26 30, // September
27 31, // October
28 30, // November
29 31 // December
30 ];
31
32 // Return the number of days for the specified month
33 return daysInMonth[month];
34}
35
Time and Space Complexity
The time complexity is O(1)
because:
- Checking if a year is a leap year involves a fixed number of arithmetic operations (
%
and logical operators), which takes constant time - Creating the
days
list with 13 elements is a constant-size operation - Accessing an element from the list by index (
days[month]
) is a constant-time operation - All operations execute in a fixed amount of time regardless of the input values
The space complexity is O(1)
because:
- The
leap
boolean variable uses constant space - The
days
list always contains exactly 13 integers, which is a fixed amount of memory - No additional data structures are created that scale with the input
- The space used remains constant regardless of the input year or month values
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Leap Year Logic
One of the most common mistakes is implementing the leap year calculation incorrectly. Developers often forget one of the conditions or use incorrect logical operators.
Incorrect implementations:
# Missing the century rule is_leap = year % 4 == 0 # Wrong: 1900 would be considered a leap year # Wrong logical operators is_leap = (year % 4 == 0 or year % 100 != 0) and (year % 400 == 0) # Wrong logic # Incorrect precedence without parentheses is_leap = year % 4 == 0 and year % 100 != 0 or year % 400 == 0 # This actually works due to operator precedence, but it's less readable
Solution: Always use clear parentheses and remember the complete rule:
is_leap_year = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
2. Off-by-One Errors with Month Indexing
Another common mistake is forgetting that months are typically 1-indexed (1-12) while arrays are 0-indexed.
Incorrect approach:
# Forgetting the placeholder at index 0 days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] return days[month] # This would return February's days when month=1
Solution: Include a placeholder at index 0 or adjust the index:
# Option 1: Placeholder at index 0 (cleaner) days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] return days[month] # Option 2: Adjust index when accessing days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] return days[month - 1]
3. Hardcoding February Without Checking Leap Year
Some implementations create the days array without considering the leap year condition for February.
Incorrect approach:
def numberOfDays(self, year: int, month: int) -> int:
days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # Always 28 for Feb
return days[month] # Wrong for leap years
Solution: Always check and update February's days based on the leap year condition:
is_leap_year = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0) days = [0, 31, 29 if is_leap_year else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
4. Using a Dictionary with Integer Keys
While using a dictionary might seem intuitive, it's unnecessarily complex for this problem.
Overcomplicated approach:
days = { 1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31 } if is_leap_year: days[2] = 29 return days[month]
Solution: Use a simple list as shown in the original solution - it's more efficient and cleaner for sequential integer keys.
Problem: Given a list of tasks and a list of requirements, compute a sequence of tasks that can be performed, such that we complete every task once while satisfying all the requirements.
Which of the following method should we use to solve this problem?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!