[백준] 12015: 가장 긴 증가하는 부분 수열 2 - JAVA
https://www.acmicpc.net/problem/12015
풀이
가장 긴 증가하는 부분수열(LIS)의 길이를 구해야 한다.
dp로 풀어보았으나 시간초과가 났다.
dp로 푸는 풀이는 N^2의 시간복잡도를 갖는다.
이분 탐색으로 푸는 방법을 채택하여 NlogN으로 시간을 줄였다.
배열을 만들어 숫자가 들어갈 위치를 찾아 그 숫자를 배열에 넣는다.
배열의 마지막 값보다 숫자가 크다면 그 다음 칸에 숫자를 넣고,
작다면 이분탐색을 통해 들어갈 위치를 찾아 갱신해 주면 되는 문제였다.
메모리: 95952KB
시간: 528ms
언어: Java 11
코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] arr = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
int[] dp = new int[N + 1];
int max = 0;
for (int i = 0; i < N; i++) {
if (arr[i] > dp[max]) {
dp[++max] = arr[i];
} else {
int idx = binarySearch(dp, 0, max, arr[i]);
dp[idx] = arr[i];
}
}
System.out.println(max);
}
private static int binarySearch(int[] arr, int left, int right, int key) {
int mid = 0;
while (left < right) {
mid = (left + right) / 2;
if (arr[mid] < key) {
left = mid + 1;
} else {
right = mid;
}
}
return right;
}
}