3307 최장 증가 부분 수열 문제 링크
#1
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Solution {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for(int t=1; t<=T; t++) {
int N = Integer.parseInt(br.readLine());
int[] arr = new int[N];
int[] dp = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=0; i<N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
for(int i=0; i<N-1; i++) {
for(int j=i+1; j<N; j++) {
if(arr[i] < arr[j]) {
dp[j] = Math.max(dp[i]+1, dp[j]);
}
}
}
int answer = 0;
for(int i=0; i<N; i++) {
answer = Math.max(answer, dp[i]);
}
StringBuilder sb = new StringBuilder();
sb.append("#").append(t).append(" ").append(answer+1);
System.out.println(sb.toString());
}
}
}

- dp로 풀이함 : O(n^2)
- 완탐으로 하는 게 가장 기본적인? 풀이인 것 같은데
- 완탐은 사실 시간복잡도가 너무 커서 dp로 풀이함
- 근데 dp로 풀고 나니까 시간 복잡도가 완탐이랑 똑같음..
#2
package week01;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class SWEA_3307_binarySearch {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for(int t=1; t<=T; t++) {
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());
}
LinkedList<Integer> result = new LinkedList<>();
int nowIndex;
for(int i=0; i<N; i++) {
nowIndex = Collections.binarySearch(result, arr[i]);
if(nowIndex >= 0) {
result.add(nowIndex, arr[i]);
}
else {
int point = (nowIndex+1)*-1;
if(point == result.size()) {
result.add(arr[i]);
}
else {
result.set(point, arr[i]);
}
}
}
sb.append("#").append(t).append(" ").append(result.size()).append("\n");
}
System.out.println(sb);
}
}

- binarysearch를 활용한 풀이 : O(nlogn)
- 이게 최장 증가 부분 수열의 길이 구하는 문제의 정석 풀이..? 라고 하더라
- 스터디원 분의 도움을 받아서 작성한 풀이..
#3
package week01;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class SWEA_3307_binarySearch {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for(int t=1; t<=T; t++) {
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());
}
LinkedList<Integer> result = new LinkedList<>();
int nowIndex;
for(int i=0; i<N; i++) {
nowIndex = Collections.binarySearch(result, arr[i]);
int point = (nowIndex+1)*-1;
if(point == result.size()) {
result.add(arr[i]);
}
else {
result.set(point, arr[i]);
}
}
sb.append("#").append(t).append(" ").append(result.size()).append("\n");
}
System.out.println(sb);
}
}

if(nowIndex >= 0) {
result.add(nowIndex, arr[i]);
}
- 이 부분은 무의미한 갱신이라는 생각이 들어서
- 없어도 되지 않나.. 라는..
- 근데 어쨌든 갱신 파트를 삭제한 건데 메모리는 증가하고 속도는 변화가 없다는 사실...
- 속도는 그렇다 치는데 메모리는 대체 왜 늘어난 거지..?
- 아하.. linkedList를 사용했기 때문에 삽입 파트에서 효율이 좋아서 add문 조금 뺀 걸로는 속도의 큰 차이가 없다는군요..
- 메모리는 반대로 linkeList가 이미 비효율적이여서 유의미한 차이가 없다네요..