728x90
백준12015 가장 긴 증가하는 부분 수열 2
이진 탐색(Binary Search)를 사용한 LIS( Longest Increasing Subsequence) 풀이
입력값이 1,000,000이 최대이므로 N^2으로는 풀 수 없음 최대 NlogN
이진탐색을 써야하는 문제인 건 알고 있는데 도대체 어디에;;
LIS 풀이법을 결국 떠올리지 못하고 해답을 찾아보았다.
새로운 배열을 만들어서 원본 배열 원소와 비교하며 새로운 배열에 차례대로 넣으면 되는 아주 간단한 풀이 방식이였다.
- LIS를 저장할 배열(lisArr)을 유지하면서 이진 탐색
- 현재 값이 lisArr의 마지막 값보다 크면 추가
- 그렇지 않다면, lisArr에서 현재 값이 들어갈 위치를 이진 탐색(lower_bound)을 사용해 찾고 교체
- 최종적으로 lisArr 배열의 길이가 LIS의 길이(LIS 그 자체가 되는 것은 아님)
const fs = require('fs');
const input = fs.readFileSync("./dev/stdin").toString().trim().split("\\n").map(v => v.split(' ').map(Number))
const [N] = input[0];
const arr = input[1];
let lisArr = [arr[0]]
for(let i = 1; i< N; i++) {
let current = arr[i]
// 현재 값이 LIS의 끝값보다 크면 추가
if(lisArr[lisArr.length - 1] < current ) lisArr.push(current);
else{
// 이진 탐색을 활용해서 들어갈 위치 찾기 (LowerBound)
let start = 0;
let end = lisArr.length - 1
while(start <= end ) {
let mid = Math.floor((start + end) / 2)
if(lisArr[mid] >= current) end = mid -1
else start = mid + 1
}
lisArr[start] = current // 찾은 위치로 값 덮어씌우기
}
}
console.log(lisArr.length)
https://www.acmicpc.net/problem/12015
728x90
반응형
'Coding Test' 카테고리의 다른 글
Leetcode 135 - Candy (Javascript) 1-pass 방식으로 풀기 (0) | 2025.04.22 |
---|---|
백준 11561 - 징검다리( Python ) (0) | 2023.03.14 |
백준 9012 - 괄호( Python ) (0) | 2023.03.06 |
백준 1049 - 기타줄( Python ) (0) | 2023.02.22 |
백준 16401 - 과자 나눠주기( Python ) (0) | 2023.02.16 |