문제
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.
예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이고, 길이는 4이다.
입력
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.
둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (-1,000,000,000 ≤ Ai ≤ 1,000,000,000)
출력
첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.
둘째 줄에는 정답이 될 수 있는 가장 긴 증가하는 부분 수열을 출력한다.
예제 입력
6
10 20 10 30 20 50
예제 출력
4
10 20 30 50
해설
가장 긴 증가하는 수열 2 문제 풀이에 추가로 LIS 배열에 들어가는 input 배열의 index를 배열로 저장한다.(idx 배열) 이 후 idx 배열의 가장 마지막 원소부터 LIS 길이를 감소시켜 가며, 처음으로 해당 길이의 index가 나오는 원소만 뽑아내 역으로 정렬하면 구하고자 하는 LIS 자체가 나오게 된다.
소스 코드
let input = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
const N = +input.shift();
input = input[0].split(' ').map(Number);
function solution(input) {
let LIS = [input[0]];
let idx = [0];
let answer = '';
for (let i = 1; i < N; i++) {
const target = input[i];
if (LIS[LIS.length - 1] < target) {
idx.push(LIS.length);
LIS.push(target);
}
else {
let min = 0;
let max = LIS.length - 1;
let mid = Math.floor((min + max) / 2);
while (min < max) {
mid = Math.floor((min + max) / 2);
if (LIS[mid] >= target) {
max = mid;
} else if (LIS[mid] < target) {
min = mid + 1;
}
}
idx.push(min);
LIS[min] = target;
}
};
let len = LIS.length - 1
for (let i = idx.length - 1; i >= 0; i--) {
if (idx[i] === len) {
answer = ' ' + input[i] + answer;
len--;
}
}
console.log(LIS.length);
console.log(answer.trim());
}
solution(input);
참고자료
'알고리즘 공부[Javascript] > 백준' 카테고리의 다른 글
[백준] 12015번 / 골드2 / 가장 긴 증가하는 부분 수열 2 / Node.js (0) | 2021.11.28 |
---|---|
[백준] 9251번 / 골드5 / LCS / Node.js (0) | 2021.11.25 |
[백준] 17219번 / 실버4 / 비밀번호 찾기 / Node.js (0) | 2021.10.30 |
[백준] 11727번 / 실버3 / 2×n 타일링 2 / Node.js (0) | 2021.10.21 |
[백준] 11724번 / 실버2 / 연결 요소의 개수 / Node.js (0) | 2021.10.20 |