티스토리 뷰
더 깔끔한 노션을 원한다면
Baekjoon 10868 최솟값 - 세그먼트 트리
처음 생각 - copyOfRange
www.notion.so
10868번: 최솟값
N(1 ≤ N ≤ 100,000)개의 정수들이 있을 때, a번째 정수부터 b번째 정수까지 중에서 제일 작은 정수를 찾는 것은 어려운 일이 아니다. 하지만 이와 같은 a, b의 쌍이 M(1 ≤ M ≤ 100,000)개 주어졌을 때는
www.acmicpc.net
처음 생각 - copyOfRange
[a,b] 구간을 copyOfRange를 통해 잘라서 최솟값을 구하는 방법을 택했다.
for(int index = 1; index<=M;index++){
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
int [] buffer = Arrays.copyOfRange(numbers,start,end + 1);
Arrays.sort(buffer);
System.out.println(buffer[0]);
}
2%에서 시간 초과!
두 번째 생각 - Comparable
index와 number를 가진 Number class를 구현하여 정렬을 해준다.
Number[] Numbers = new Number[N];
for(int index = 1;index<=N;index++){
numbers[index] = Integer.parseInt(br.readLine());
Numbers[index - 1] = new Number(index, numbers[index]);
}
Arrays.sort(Numbers);
그런 뒤, Numbers의 index가 [a,b] 구간에 포함되는지 검사해준다.
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
for(int number = 0;number<N;number++){
if(start <= Numbers[number].index && Numbers[number].index <= end) {
System.out.println(Numbers[number].number);
break;
}
}
15%에서 시간초과
결론은 세그먼트 트리
Hint를 보니 세그먼트 트리라는 자료구조를 사용해야 했다.
세그먼트 트리(Segment Tree)
데이터를 효율적으로 저장하고, 빠른 시간에 탐색, 수정 및 추가 삭제 연산을 진행
www.notion.so
위에 링크는 세그먼트 트리에 대한 이해를 돕는 포스팅이다.
전체 코드
/**
* @포인트 세그먼트 트리로 풀어야 하는 문제
* @포인트 구간의 최대, 최소, 합을 구하는 문제는 세그먼트 트리로 풀어야 한다!
*/
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
P10868();
}
static void P10868() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N, M;
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
int[] numbers = new int[N];
for (int index = 0; index < N; index++) {
numbers[index] = Integer.parseInt(br.readLine());
}
SegmentTree segObj = new SegmentTree(numbers, N);
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
System.out.println(segObj.query(a - 1, b - 1, 1, 0, N - 1));
}
}
static class SegmentTree {
static int[] segmentArr;
SegmentTree(int[] arr, int n) {
segmentArr = new int[n * 4];
Arrays.fill(segmentArr, Integer.MAX_VALUE);
init(arr, 0, n - 1, 1);
}
static int init(int arr[], int left, int right, int node) {
if (left == right)
return segmentArr[node] = arr[left];
int mid = (left + right) / 2;
return segmentArr[node] = Math.min(init(arr, left, mid, node * 2), init(arr, mid + 1, right, node * 2 + 1));
}
static int query(int start, int end, int node, int nodeLeft, int nodeRight) {
if (start > nodeRight || end < nodeLeft)
return Integer.MAX_VALUE;
if (start <= nodeLeft && end >= nodeRight)
return segmentArr[node];
int mid = (nodeLeft + nodeRight) / 2;
return Math.min(query(start, end, node * 2, nodeLeft, mid), query(start, end, node * 2 + 1, mid + 1, nodeRight));
}
}
}
'알고리즘' 카테고리의 다른 글
Baekjoon 2583 영역 구하기 - DFS (0) | 2020.10.13 |
---|---|
Baekjoon 2042 구간 합 구하기 - 세그먼트 트리(구간 합, 수정) (0) | 2020.10.09 |
세그먼트 트리(Segment Tree) (0) | 2020.10.09 |
풀어보면 좋은 문제 (0) | 2020.10.09 |
Baekjoon 3111 검열 - 문자열+스택 (0) | 2020.10.04 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- C++
- Olympiad
- JPA
- 이펙티브 자바
- 프로그래머스
- kotest
- Algorithm
- node.js
- 테라폼
- 클린 아키텍처
- 디자인패턴
- 정규표현식
- BAEKJOON
- kkoon9
- 알고리즘
- 디자인 패턴
- MSA
- Spring
- 이팩티브 자바
- Spring Boot
- 백준
- 클린 코드
- AWS
- 코테
- Java
- BOJ
- Effective Java
- 객체지향
- programmers
- Kotlin
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함