문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/150370
[이 문제는 프로그래머스에서 푼 문제입니다.]
이 문제는 문제에서 요구하는 조건을 잘 읽어보고 하나씩 구현해나가면 됩니다. 저같은 경우는 HashMap을 이용하여 terms 배열을 재배치하여 privacies 배열에서 유효 기간을 탐색하여 반복문을 이용하여 탐색했을 때에 비해서 탐색 속도를 O(N)에서 O(1)로 감소시켰습니다. 이어서 날짜 계산 시 split으로 .을 기준으로 자른 후 날짜 계산을 진행했습니다.
제가 난항을 겪은 부분은
이 부분만 유의하시면 성공적으로 푸실 수 있습니다.
다음은 코드입니다.
import java.util.*;
class Solution {
public int[] solution(String today, String[] terms, String[] privacies) {
// terms 배열 재배치
Map<String, Integer> req = new HashMap<>();
for(int i=0;i<terms.length;i++){
StringTokenizer st = new StringTokenizer(terms[i]);
String type = st.nextToken();
int term = Integer.parseInt(st.nextToken());
req.put(type,term);
}
// privacies 배열 탐색
Queue<Integer> res = new LinkedList<>();
for(int i=0;i<privacies.length;i++){
StringTokenizer st = new StringTokenizer(privacies[i]);
String date = st.nextToken();
String type = st.nextToken();
int term = req.get(type);
boolean isAnswer = !isValidPrivacies(today, date, term);
if(isAnswer) res.add(i+1);
}
int[] answer = new int[res.size()];
int idx = 0;
while(!res.isEmpty()){
int curr = res.poll();
answer[idx] = curr;
idx++;
}
return answer;
}
static boolean isValidPrivacies(String today, String date, int term){
// . 기준으로 문자열 자른 배열 생성
// .을 기준으로 자를 경우 \\. 으로 처리 필요
String[] todayArr = today.split("\\.");
String[] dateArr = date.split("\\.");
// 오늘 날짜 추출
int todayYear = Integer.parseInt(todayArr[0]);
int todayMonth = Integer.parseInt(todayArr[1]);
int todayDay = Integer.parseInt(todayArr[2]);
// 비교할 날짜 추출
int currYear = Integer.parseInt(dateArr[0]);
int currMonth = Integer.parseInt(dateArr[1]);
int currDay = Integer.parseInt(dateArr[2]);
// 연도가 바뀌는 수 : + term/12
// 달이 바뀌는 수 : + term%12
// 일이 바뀌는 수 : - 1
int newYear = currYear + (term/12);
int newMonth = currMonth + (term%12);
// 달이 12보다 클 경우 연도를 1 증가
if(newMonth > 12){
newYear++;
newMonth -= 12;
}
int newDay = currDay - 1;
// 일 수가 1보다 작을 경우 달 수 1 감소
if(newDay==0){
newMonth--;
newDay = 28;
}
// 유효기간 만료 연도가 현재 연도보다 클 경우 아직 유효
if(todayYear < newYear) return true;
// 유효기간 만료 연도가 현재 연도보다 작을 경우 만료
else if(todayYear > newYear) return false;
// 유효기간 만료 연도가 현재 연도와 같을 경우 달 수 비교
else{
// 유효기간 만료 달 수가 현재 달 수보다 클 경우 아직 유효
if(todayMonth < newMonth) return true;
// 유효기간 만료 달 수가 현재 달 수보다 작을 경우 만료
else if(todayMonth > newMonth) return false;
// 유효기간 만료 달 수가 현재 달 수와 같을 경우 일 수 비교
else{
// 유효기간 만료 일 수가 현재 일 수보다 클 경우 아직 유효
if(todayDay < newDay) return true;
// 유효기간 만료 일 수가 현재 일 수보다 작을 경우 만료
else if(todayDay > newDay) return false;
// 일 수가 현재 일 수와 같다면 유효
else return true;
}
}
}
}