
이번 문제는
- 출력값을 나온 DFS 결과가 올바른 순서 여부 판단
하는 문제였습니다.
💡 여기서 주의할 점!
st.hasNextTokens()을 통해, 예상 Index 파악contains()을 통해, 존재 여부 판단 + count 함수를 통한 접근 제어import java.util.*;
import java.io.*;
public class Main {
static class Node {
int idx, count;
Node(int idx, int count) {
this.idx = idx;
this.count = count;
}
}
public static void main(String[] args) throws Exception {
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
int seq = Integer.parseInt(br.readLine());
List<List<Integer>> list = new ArrayList<>();
for(int i = 0; i < seq + 1; i++) {
list.add(new ArrayList<>());
}
StringTokenizer st;
for(int i = 0; i < seq - 1; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
list.get(a).add(b);
list.get(b).add(a);
}
boolean flag = false;
ArrayDeque<Node> stack = new ArrayDeque<>();
st = new StringTokenizer(br.readLine());
if (Integer.parseInt(st.nextToken()) == 1) {
stack.push(new Node(1, 0));
while(st.hasMoreTokens()) {
Node node = stack.peek();
if(list.get(node.idx).size() <= node.count) {
stack.pop();
continue;
}
int nextIdx = Integer.parseInt(st.nextToken());
if (list.get(node.idx).contains(nextIdx)) {
node.count++;
stack.push(new Node(nextIdx, 1));
continue;
}
flag = true;
break;
}
System.out.println(!flag ? 1 : 0);
} else {
System.out.println(0);
}
}
}

O(N)으로 비효율적O(N^2)만큼 진행, 정점은 100,000까지 가능contains()는 시간 복잡도가 평균 O(1), 최악일 때만 O(N)으로 효율적import java.util.*;
import java.io.*;
public class Main {
static class Node {
int idx, count;
Node(int idx, int count) {
this.idx = idx;
this.count = count;
}
}
public static void main(String[] args) throws Exception {
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
int seq = Integer.parseInt(br.readLine());
List<Set<Integer>> list = new ArrayList<>();
for(int i = 0; i < seq + 1; i++) {
list.add(new HashSet<>());
}
StringTokenizer st;
for(int i = 0; i < seq - 1; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
list.get(a).add(b);
list.get(b).add(a);
}
boolean flag = false;
ArrayDeque<Node> stack = new ArrayDeque<>();
st = new StringTokenizer(br.readLine());
if (Integer.parseInt(st.nextToken()) == 1) {
stack.push(new Node(1, 0));
while(st.hasMoreTokens()) {
Node node = stack.peek();
if(list.get(node.idx).size() <= node.count) {
stack.pop();
continue;
}
int nextIdx = Integer.parseInt(st.nextToken());
if (list.get(node.idx).contains(nextIdx)) {
node.count++;
stack.push(new Node(nextIdx, 1));
continue;
}
flag = true;
break;
}
System.out.println(!flag ? 1 : 0);
} else {
System.out.println(0);
}
}
}

hashCode()를 기반으로 해시 버킷을 찾아가고, 그 안에서 equals()로 최종 비교.hashCode() 구현이 잘 되어 있으면 평균 O(1)의 성능을 보장함.| 자료구조 | contains() 시간복잡도 | 내부 구조 |
|---|---|---|
| List | O(N) | 배열 기반 순차 탐색 (ArrayList) |
| HashSet | 평균 O(1) / 최악 O(N) | Hash Table 기반, key의 hashCode와 equals로 탐색 |
hashCode()는 어디서 정의되어 있을까?HashCode()?hashCode() Object 클래스에 정의된 메소드로, 객체를 식별하는 정수형 해시값(int)을 반환자바의 모든 객체는 Object 클래스를 상속, hashCode함수는 아래와 같이 정의되어 있음
public native int hashCode();
hashCode(), wait(), notify(), clone() 등contains()의 시간복잡도가 다르다는 걸 까달음