본문 바로가기

LeetCode

[LeetCode] - 1154. Day of the Year

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;
    }
}

 

이 코드의 로직은 :

  1. 날짜 문자열 분리 :
    • substring 메소드를 사용하여 연도, 월, 일을 각각 year, month, day 변수에 저장합니다.
  2. 윤년 확인 :
    • 윤년인지 확인하는 조건을 계산하여 isLeap 변수에 저장합니다.
    • 윤년의 조건 :
      • 연도가 400으로 나누어 떨어지면 윤년
      • 연도가 4로 나누어 떨어지고 100으로 나누어 떨어지지 않으면 윤년
  3. 월별 일수 배열 초기화 :
    • daysInMonth 배열을 사용하여 각 월의 일수를 저장합니다. 0번 인덱스는 사용하지 않습니다.
  4. 윤년일 경우 2월의 일수 조정 :
    • isLeap가 true이면 2월의 일수를 29일로 설정합니다.
  5. 현재 월 이전까지의 총 일수 계산 :
    • 현재 월 이전까지의 총 일수를 days 변수에 저장합니다.
  6. 현재 월의 일수 더하기 :
    • 현재 월의 일수를 더하여 총 일수를 반환합니다.
  • 시간 복잡도 : O(1)
    • 날짜 문자열을 파싱하는 작업과 윤년 여부를 확인하는 작업은 모두 상수 시간에 수행됩니다.
    • 월별 일수를 더하는 작업은 최대 11번의 덧셈 연산을 포함하여 상수 시간에 수행됩니다.
    • 따라서 전체 시간 복잡도는 O(1)입니다.
  • 공간 복잡도 : O(1)
    • daysInMonth 배열은 크기가 고정된 배열이며, 추가적인 변수들은 상수 공간만을 사용합니다.
    • 따라서 전체 공간 복잡도는 O(1)입니다.

Runtime 결과