본문 바로가기

CS ﹒ Algorithm/Baekjoon

Java 백준 문제풀이 (42) 1253 : 좋다

실패 아니라고..

 

 

이분탐색, 투포인터 등으로 풀 수 있는 문제다.

투포인터 알고리즘에 대한 설명은 지난 글들에서 충분히 다루었기 때문에 생략한다.

투포인터 알고리즘을 모르면 아래의 기초 문제들을 먼저 풀어보자.

 

https://7357.tistory.com/235?category=1066252 

 

Java 백준 문제풀이 (40) 2018번: 수들의 합5

투포인터 알고리즘의 시간복잡도는 기본적으로 O(N)이지만 배열이 정렬된 상태에서만 사용할 수 있기 때문에 정렬이 필요할 경우 일반적으로 많이 쓰이는 병합 정렬, 퀵 정렬을 생각했을 때 O(nlo

7357.tistory.com

https://7357.tistory.com/236?category=1066252 

 

Java 백준 문제풀이 (41) 1940번 : 주몽

투 포인터를 사용하는 문제 자체가 처음이라면 이전 글을 먼저 읽어보자. 보다 친절하게 설명해놨다. 사실 쉬운 문제라서 딱히 이론적인 부분을 이해해야 하는 건 아니긴 하다. https://7357.tistory.c

7357.tistory.com

 

 

일단 늘 하던 방식대로, 예제를 손으로 그려서 어떻게 풀면 좋을지 생각해보자.

나는 손으로 그렸으나 캡쳐해서 옮기기 귀찮으니 키보드로 작성하겠다.

 

1 2 3 4 5 6 7 8 9 10
Lpointer Rpointer K              

 

와.. 이렇게만 했을 뿐인데 벌써 완전 괜찮은 풀이법이 탄생한 것 같다.

우선 수를 정렬하고, K를 늘려가며 K보다 작은 수의 범위에서 

Sum이 K보다 크다면 Rpointer--; , Sum이 K보다 작다면 Lpointer++;하면 되겠네요 ㄷ ㄷ

 

늘 그렇듯 풀이법이 너무 쉽게 떠오르면 틀리더라

 

ㅋㅋ

 

 

저 방식으로 풀고 1시간을 맞왜틀하느라 시간 날렸다.

위 방법으로는 다음 조건들을 만족시키지 못한다.

1. 처음 주어지는 3개의 수 중 K와 중복되는 수가 존재하는 경우 ( 예 : 0 3 3 ) 

2. 음수가 존재하는 경우 ( 예 : -2 0 2 )

 

 

따라서 매번 배열의 시작부터 끝까지 모든 경우의 수를 체크해서 경우의 수를 구해야 한다..

결국 N개의 원소를 가진 배열을 N번 반복하므로 이 풀이 방법은 O(N^2)의 시간 복잡도를 가지게 된다.

 

이 부분만 실수하지 않는다면 투 포인터 알고리즘을 알고 있다는 가정 하에 어려운 문제가 아니기에 더 이상의 설명은 생략한다.

 

 

 

 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.util.*;
import java.io.*;
 
public class Main {
    public static void main(String[] args) throws Exception {
        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());
        }
 
        Arrays.sort(arr);
 
        int answer = 0;
        for (int i=0; i<N; i++) {
            int left = 0;
            int right = N - 1;
            int sum;
 
            while (left < right) {
                if ( left == i ) {
                    left++;
                }
                else if ( right == i ) {
                    right--;
                }
                else {
                    sum = arr[left] + arr[right];
 
                    if (sum == arr[i]) {
                        answer++;
                        break;
                    }
 
                    if (sum > arr[i]) {
                        right--;
                    }
 
                    if (sum < arr[i]) {
                        left++;
                    }
                }
            }
        }
 
        System.out.println(answer);
    }
}
cs