💡문제 분석 요약
1,2,3 으로만 이루어져 있는 길이가 N인 좋은 수열 중 가장 작은 수를 구하는 문제이다.
좋은 수열은 임의의 길이의 인접한 두 개의 부분 수열이 동일한 것이 없는 수열이다.
- 시간 제한: 1초
- 메모리 제한: 128MB
💡알고리즘 설계
- 백트래킹 메서드 (`backTrack`)
- 1, 2, 3 을 순차적으로 현재 수열(`seq`)에 추가한다.
- `seq` 에 숫자를 추가했을 때 좋은 수열인지 검사한다. (`isGoodSeq`)
- 좋은 수열이면 숫자를 추가하여 메서드를 재귀 호출한다.
- `seq`의 길이가 N이 되면 출력하고 프로그램을 종료한다.
- 1, 2, 3 을 순차적으로 현재 수열(`seq`)에 추가한다.
- 좋은 수열인지 검사 (`isGoodSeq`)
- 길이가 1인 부분 수열부터 시작해서 수열의 길이 절반까지 늘려가며 검사한다. (1부터 seq.length() / 2 까지)
- 각 길이에 대해, 마지막 i길이의 부분 수열과 바로 앞의 같은 길이의 부분 수열을 비교한다.
- 두 부분 수열이 같으면 좋은 수열이 아니므로 false를 리턴한다.
💡코드
import java.io.*;
public class Main {
static int N;
static void backTrack(String seq) {
if(seq.length() == N) {
System.out.println(seq);
System.exit(0);
}
for(int i=1; i<=3; i++) {
if(isGoodSeq(seq+i))
backTrack(seq+i);
}
}
static boolean isGoodSeq(String seq) {
int end = seq.length() / 2;
for(int i=1; i<=end; i++) {
String s1 = seq.substring(seq.length()-i*2, seq.length()-i);
String s2 = seq.substring(seq.length()-i, seq.length());
if(s1.equals(s2)) return false;
}
return true;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
backTrack("");
}
}
💡시간복잡도
백트래킹 메서드에서 $O(3^N)$이고, 좋은 수열인지 검사하는 메서드에서 각 수열에 대해 $O(N/2)$ 시간이 걸린다.
따라서 전체 시간복잡도는 $O(N*3^N)$이다.
💡 느낀점 or 기억할정보
좋은 수열인지 판별하는 코드를 생각하는데 오래걸렸다. 결국 레퍼런스를 찾아봤지만 생각보다 간단해서 아직 생각이 많이 부족하다는 느낌이 들었다ㅜ
프로그램을 종료하는 `System.exit(0)` 기억하기!
반응형
'알고리즘 문제 > 백준' 카테고리의 다른 글
[백준] 1654번: 랜선 자르기 (Java) (0) | 2024.07.31 |
---|---|
[백준] 2805번: 나무 자르기 (Java) (0) | 2024.07.30 |
[백준] 1759번: 암호 만들기 (Java) (0) | 2024.07.26 |
[백준] 1182번: 부분수열의 합 (Java) (0) | 2024.07.25 |
[백준] 6987번: 월드컵 (Java) (3) | 2024.07.24 |
댓글