LeetCode는 프로그래밍 문제를 풀며 코딩 실력을 향상할 수 있는 온라인 플랫폼입니다. 다양한 알고리즘 및 데이터 구조 문제를 제공하며, 면접 대비에 유용합니다. 해당 문제는, LeetCode Problems에서 볼 수 있는 난이도 '쉬움 (Easy)' 단계인 "Day of the Year" 문제입니다.
--> https://leetcode.com/problems/day-of-the-year/description/
문제 :
Given a string date representing a Gregorian calendar date formatted as YYYY-MM-DD, return the day number of the year.
Example 1 :
Input : date = "2019-01-09"
Output : 9
Explanation : Given date is the 9th day of the year in 2019.
Example 2 :
Input : date = "2019-02-10"
Output : 41
Constraints :
- date.length == 10
- date[4] == date[7] == '-', and all other date[i]'s are digits
- date represents a calendar date between Jan 1st, 1900 and Dec 31th, 2019.
이 문제는 주어진 문자열 date가 YYYY-MM-DD 형식으로 나타낸 그레고리력 날짜를 나타낼 때, 해당 날짜가 그 해의 몇 번째 날인지를 반환하는 문제입니다.
class Solution {
public int dayOfYear(String date) {
int year = Integer.parseInt(date.substring(0, 4));
int month = Integer.parseInt(date.substring(5, 7));
int day = Integer.parseInt(date.substring(8, 10));
boolean isLeap = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
int days = 0;
if (isLeap) {
switch (month) {
case 1 :
days = 0;
break;
case 2 :
days = 31;
break;
case 3 :
days = 29 + 31;
break;
case 4 :
days = 29 + 31 + 31;
break;
case 5 :
days = 29 + 31 + 31 + 30;
break;
case 6 :
days = 29 + 31 + 31 + 30 + 31;
break;
case 7 :
days = 29 + 31 + 31 + 30 + 31 + 30;
break;
case 8 :
days = 29 + 31 + 31 + 30 + 31 + 30 + 31;
break;
case 9 :
days = 29 + 31 + 31 + 30 + 31 + 30 + 31 + 31;
break;
case 10 :
days = 29 + 31 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
break;
case 11 :
days = 29 + 31 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
break;
case 12 :
days = 29 + 31 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
break;
}
} else {
switch (month) {
case 1 :
days = 0;
break;
case 2 :
days = 31;
break;
case 3 :
days = 28 + 31;
break;
case 4 :
days = 28 + 31 + 31;
break;
case 5 :
days = 28 + 31 + 31 + 30;
break;
case 6 :
days = 28 + 31 + 31 + 30 + 31;
break;
case 7 :
days = 28 + 31 + 31 + 30 + 31 + 30;
break;
case 8 :
days = 28 + 31 + 31 + 30 + 31 + 30 + 31;
break;
case 9 :
days = 28 + 31 + 31 + 30 + 31 + 30 + 31 + 31;
break;
case 10 :
days = 28 + 31 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
break;
case 11 :
days = 28 + 31 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
break;
case 12 :
days = 28 + 31 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
break;
}
}
return day + days;
}
}
처음에 저는 이렇게 정신 나간 사람 처럼 코드를 짜보기도 했습니다. 하지만 나중에는 이렇게 개선시켰죠
class Solution {
public int dayOfYear(String date) {
int year = Integer.parseInt(date.substring(0, 4));
int month = Integer.parseInt(date.substring(5, 7));
int day = Integer.parseInt(date.substring(8, 10));
boolean isLeap = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Adjust February for leap years
if (isLeap) {
daysInMonth[2] = 29;
}
// Calculate the number of days before the current month
int days = 0;
for (int i = 1; i < month; i++) {
days += daysInMonth[i];
}
// Add the days of the current month
return days + day;
}
}
이 코드의 로직은 :
- 날짜 문자열 분리 :
- substring 메소드를 사용하여 연도, 월, 일을 각각 year, month, day 변수에 저장합니다.
- 윤년 확인 :
- 윤년인지 확인하는 조건을 계산하여 isLeap 변수에 저장합니다.
- 윤년의 조건 :
- 연도가 400으로 나누어 떨어지면 윤년
- 연도가 4로 나누어 떨어지고 100으로 나누어 떨어지지 않으면 윤년
- 월별 일수 배열 초기화 :
- daysInMonth 배열을 사용하여 각 월의 일수를 저장합니다. 0번 인덱스는 사용하지 않습니다.
- 윤년일 경우 2월의 일수 조정 :
- isLeap가 true이면 2월의 일수를 29일로 설정합니다.
- 현재 월 이전까지의 총 일수 계산 :
- 현재 월 이전까지의 총 일수를 days 변수에 저장합니다.
- 현재 월의 일수 더하기 :
- 현재 월의 일수를 더하여 총 일수를 반환합니다.
- 시간 복잡도 : O(1)
- 날짜 문자열을 파싱하는 작업과 윤년 여부를 확인하는 작업은 모두 상수 시간에 수행됩니다.
- 월별 일수를 더하는 작업은 최대 11번의 덧셈 연산을 포함하여 상수 시간에 수행됩니다.
- 따라서 전체 시간 복잡도는 O(1)입니다.
- 공간 복잡도 : O(1)
- daysInMonth 배열은 크기가 고정된 배열이며, 추가적인 변수들은 상수 공간만을 사용합니다.
- 따라서 전체 공간 복잡도는 O(1)입니다.
'LeetCode' 카테고리의 다른 글
[LeetCode] - 1436. Destination City (0) | 2024.07.31 |
---|---|
[LeetCode] - 1252. Cells With Odd Values in a Matrix (0) | 2024.07.30 |
[LeetCode] - 1089. Duplicate Zeros (0) | 2024.07.30 |
[LeetCode] - 1051. Height Checker (0) | 2024.07.30 |
[LeetCode] - 1108. Defanging an IP Address (0) | 2024.07.29 |