알고리즘/백준

11053번, 12015번 - 가장 긴 증가하는 부분 수열

fleur75 2023. 8. 3. 20:22

1️⃣ 이분탐색

 

✏️ 풀이 과정

해결 아이디어는 C라는 배열에 차례대로 입력값을 넣어가면서 수열을 업데이트하는것입니다. 이 때 이분탐색이 이용되는데 어떤 수를 넣을 때 이분탐색을 통해서 C의 어떤 자리에 이 수를 넣어야 하는지 체크합니다. 만약 이 자리가 기존에 채워져있는 인덱스일 경우(더 큰 수가 있는 경우가 해당됩니다.) 해당 수를 교체합니다. 이렇게 하면 해당 자리의 수가 작아지기 때문에 결과적으로 나중에 더 길어질 때 더 작은 수들을 채워넣을 여력이 생기게 됩니다.(중간 부분이 실제 수열과 달라지겠지만 길이 자체는 같습니다.)  그리고 채워지지 않은 인덱스인 경우(가장 큰 경우) 해당 자리에 넣고 사이즈를 증가시켜줍니다.

 

C 배열은 항상 오름차순으로 정렬되기 때문에 추가적인 정렬 없이도 항상 이분탐색을 실행할 수 있습니다. 

 

⏱ 시간 복잡도

이분 탐색을 N번 실시하기 때문에 O(NlogN)이 됩니다.

 

💻 코드

Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main{
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		int N = Integer.parseInt(br.readLine());
		int[] arr = new int[N];
		int[] C = new int[N];
		st = new StringTokenizer(br.readLine());
		int size = 0;
		int pos;
		for (int i = 0; i < N; i++) {
			arr[i] = Integer.parseInt(st.nextToken());
			pos = Arrays.binarySearch(C, 0, size, arr[i]);
			if(pos >= 0) {
				continue;
			}
			pos = -1 * (pos + 1);
			C[pos] = arr[i];
			if(pos == size) {
				size++;
			}
		}
		System.out.println(size);
		br.close();
	}
}