코딩테스트/백준_Java
Q. 15654 자바 : N과M(5)
Ski_
2023. 4. 24. 22:59
Q. 15654 자바 : N과M(5)
문제 : boj.kr/15654
실버 3 난이도의 문제이다.
N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
N개의 자연수는 모두 다른 수이다.
- N개의 자연수 중에서 M개를 고른 수열을 출력하는 문제이다.
주의해야 할 점은 수열은 사전 순으로 증가하는 순서로 출력한다 라는 내용 때문에 수열을 입력 받은 뒤 정렬이 한번 필요하다.
이 문제는 백트래킹과 재귀함수를 이용해 풀었고,
이전 계산한 결과를 배열에 저장하고, 깊이가 최대일 때 까지 탐색을 완료하면 저장한 결과를 출력하는 방식으로 풀었다.
시간 복잡도를 계산하면, M과 N이 최대 8이므로
1. 계산 - O(N^M)
2. 출력 - O(NM)
두 계산은 연관이 없으므로 곱해줄 필요는 없으므로 약O(N^M)의 시간복잡도를 가진다.
8^8 = 16,777,216으로 시간초과는 걱정하지 않아도 된다.
자료형은 백트래킹한 수열 저장은 int형 배열에, 중복 여부 확인은 HashSet을 이용했다. 역시 int 범위 내에서 모두 해결할 수 있다.
풀이는 아래와 같다.
import java.io.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;
public class Main {
static FastReader scan = new FastReader();
static StringBuilder sb = new StringBuilder();
static int N, M;
static int[] input_val;
static HashSet<Integer> hashSet;
static int[] prev_val;
static void input() {
N = scan.nextInt();
M = scan.nextInt();
hashSet = new HashSet<>();
input_val = new int[N];
prev_val = new int[M];
for (int i = 0; i < N; i++) input_val[i] = scan.nextInt();
}
static void pro() {
Arrays.sort(input_val);
recur_func(0);
System.out.println(sb);
}
static void recur_func(int depth) {
if (depth == M) {
for (int i = 0; i < M; i++) {
sb.append(prev_val[i]).append(' ');
}
sb.append('\n');
}else {
for (int i = 0; i < N; i++){
if(hashSet.add(input_val[i])) {
prev_val[hashSet.size() - 1] = input_val[i];
recur_func(depth + 1);
hashSet.remove(input_val[i]);
}
}
}
}
public static void main(String[] args) {
input();
pro();
}
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
반응형