Category: Easy | Concepts used: Modulo operator, logical AND/OR
Problem Statement
Given a year n, determine whether it is a leap year.
A leap year has 366 days instead of 365 (an extra day, Feb 29). The rules are as follows:
- The year must be divisible by 4.
- If the year is divisible by 100, it is not a leap year, unless it is also divisible by 400.
Input : n = 2024
Output: True (Leap Year)
Input : n = 1900
Output: False (Not a Leap Year)
Examples (with edge cases)
| # | Year | Leap? | Why |
|---|---|---|---|
| 1 | 2024 | Yes | Divisible by 4, not divisible by 100 |
| 2 | 2023 | No | Not divisible by 4 |
| 3 | 1900 | No | Divisible by 100 but not by 400 (century exceptions) |
| 4 | 2000 | Yes | Divisible by 100 and by 400 |
| 5 | 0 | Yes | Year 0 is divisible by 400 โ edge case, but rules apply mathematically |
โ ๏ธ Common Beginner Mistake
Mistake Impact Fix Checking only year % 4 == 01900is wrongly marked as a Leap YearAlso check % 100and% 400exceptionsWrong order of conditions Century override fails or outputs bug Check the century exception ( % 100) before the 400 override
Before You Code: Clarify the Contract
Before choosing an algorithm, confirm whether zero and negative values are allowed, how large the input can be, and what should happen when an arithmetic result exceeds the chosen Java type. The examples use the contract stated in this article, but an interview answer should say these assumptions aloud.
Analogy: The Leap Year Club Bouncers
Imagine a VIP club called โThe Leap Year Clubโ. You are a year trying to get in. There are three gatekeepers at the entrance:
- Gatekeeper 1 (The divisible-by-4 check): โIf you are not divisible by 4, you are rejected immediately. Go home!โ
- Gatekeeper 2 (The divisible-by-100 check): โAre you a century year? If you are a normal year, pass right through. If you are a century year, step aside. You must see the Chief.โ
- Gatekeeper 3 (The divisible-by-400 check - The Chief): โAh, a century year! Show me your special pass. If you are divisible by 400, you are allowed in. If not, you are rejected!โ
Solution 1 โ Straightforward if-else Chain
This is the most intuitive approach, checking filters step-by-step.
Intuition
By handling the negative path early, we simplify the logic. If a year is not divisible by 4, it is immediately discarded. If it is divisible by 4, we check if itโs a century. If not, it is a leap year. If it is a century, it must be divisible by 400 to enter.
public class LeapYear {
public static boolean isLeapYear(int year) {
if (year % 4 != 0) {
return false; // Not divisible by 4 -> definitely not leap
} else if (year % 100 != 0) {
return true; // Divisible by 4, not a century year -> leap
} else {
// Century year -> must be divisible by 400
return year % 400 == 0;
}
}
public static void main(String[] args) {
System.out.println(isLeapYear(2024)); // true
System.out.println(isLeapYear(1900)); // false
System.out.println(isLeapYear(2000)); // true
System.out.println(isLeapYear(2023)); // false
}
}
Output:
true
false
true
false
Dry Run (year = 1900)
Step 1: 1900 % 4 == 0 -> Condition (year % 4 != 0) is false. Continue.
Step 2: 1900 % 100 == 0 -> Condition (year % 100 != 0) is false. Continue (century year).
Step 3: 1900 % 400 == 300 (not 0) -> Returns false.
Result: false (NOT a leap year)
Solution 2 โ Single Boolean Expression
This approach condenses the same logic into a single expression using logical operators.
Intuition
A year is a leap year if it is divisible by 4 AND it is either:
- Not divisible by 100, OR
- Divisible by 400.
public class LeapYearOneLiner {
public static boolean isLeapYear(int year) {
// Leap if: divisible by 4 AND (not divisible by 100 OR divisible by 400)
return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
}
public static void main(String[] args) {
System.out.println(isLeapYear(2024)); // true
System.out.println(isLeapYear(1900)); // false
System.out.println(isLeapYear(2000)); // true
}
}
Output:
true
false
true
๐ Visual Flowchart
graph TD
Start["Year Y"] --> C1{"Y % 4 == 0?"}
C1 -->|No| Reject["Not a Leap Year"]
C1 -->|Yes| C2{"Y % 100 == 0?"}
C2 -->|No| Accept["Leap Year (366 days)"]
C2 -->|Yes| C3{"Y % 400 == 0?"}
C3 -->|Yes| Accept
C3 -->|No| Reject
Interviewer Insights
This is a great question to test edge-case coverage and communication skills.
Follow-up questions you might get:
- โWhat test cases would you write for this function?โ โ Mention the boundary years, centurial milestones, and standard years:
2024(Typical Leap Year)1900(Centurial, Not Leap Year)2000(Centurial Leap Year)2023(Typical Non-Leap Year)
- โWhy do we check % 400 only after % 100?โ โ Because checking divisibility by 400 only serves to override the century exception. It is computationally more optimal to evaluate it only when needed.
Quick Recap
| Approach | Time Complexity | Space Complexity | Readability | Interview Signal |
|---|---|---|---|---|
| if-else chain | (O(1)) | (O(1)) | High | Clean structure, excellent for explaining step-by-step logic |
| Single boolean | (O(1)) | (O(1)) | Medium | Concise representation, demonstrates strong control over logical expressions |
- Author
- TechByteByByte Editorial Team
- Reviewed by
- TechByteByByte Admin
- Published
- Last reviewed