⚙️알고리즘/Java

백준) 1920 : 수 찾기

i_zzy 2024. 1. 8. 17:57

⏰문제

시간 제한 메모리 제한 제출 정답 맞힌 사람 정답 비율
1 초 128 MB 240673 73774 49011 29.86%

 

문제

N개의 정수 A[1], A[2], …, A[N]이 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 프로그램을 작성하시오.

 

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들이 A안에 존재하는지 알아내면 된다. 모든 정수의 범위는 -231 보다 크거나 같고 231보다 작다.

 

출력

M개의 줄에 답을 출력한다. 존재하면 1을, 존재하지 않으면 0을 출력한다.

 

예제 입력 1

5
4 1 5 2 3
5
1 3 7 9 5

 

예제 출력 1

1
1
0
0
1

 

 

💡풀이

이분탐색을 이용하면 쉽게 풀 수 있다. 이분탐색은 데이터의 가운데에 있는 값과 키 값(찾고자 하는 값)과 비교하여 다음 검색의 위치를 결정하고 검색을 계속 진행하는 방법이다. 즉,간단히 말하자면 우리가 잘 알고 있는 Up, Down 게임과 같다. 

검색하는 과정은 다음과 같다. 

① 데이터의 중앙에 있는 값을 고른다. 

②  중앙값과 키값을 비교한다. 

    ② -1. 중앙 값과 키값이 일치하면 탐색을 종료한다. 

    ② -2. 키값 < 중앙값 : 데이터의 왼쪽 반에 대해서 새로 검색한다. 

    ② -3. 키값 > 중앙값 :  데이터의 오른쪽 반에 대해서 새로 검색한다. 

③  찾고자 하는 값을 찾을 때까지 ②번을 반복한다. 

 

 

⌨️ 코드

1. 직접 구현

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));

        int N = Integer.parseInt(br.readLine());

        int[] A = new int[N];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for(int i=0; i< N; i++){
            A[i] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(A);

        int M = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());
        for(int i=0; i< M; i++){
            int num = Integer.parseInt(st.nextToken());
            // 이분 탐색

            int start = 0;
            int end = A.length - 1;
            boolean flag = false;

            while(start <= end){
                int mid = (start + end)/2;

                if(A[mid] > num){//중앙의 숫자보다 작으면 앞에서
                    end = mid-1;
                }
                else if(A[mid] < num){
                    start = mid+1;
                }
                else{//num이 같다면 찾음
                    System.out.println(1);
                    flag = true;
                    break;
                }
            }

            if(!flag){//못 찾음
                System.out.println(0);
            }
        }
    }//main
}

 

 

2. Arrays클래스의 binarySearch 메소드 사용

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));
        int N = Integer.parseInt(br.readLine());

        int[] A = new int[N];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for(int i=0; i< N; i++){
            A[i] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(A);

        int M = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());

        for(int i=0; i < M; i++){

            int num = Integer.parseInt(st.nextToken());
            if(Arrays.binarySearch(A, num) < 0){
                System.out.println(0);
            }
            else{
                System.out.println(1);
            }

//            System.out.println("위치"+Arrays.binarySearch(A, num));

        }

    }//main
}

 

- Arrays 클래스는 binarySearch메소드를 제공하고 있다. 

반환값은 key값이 존재하면 key값의 위치를 알려주고, 존재하지 않으면 key값의 가장 가까운 위치를 알려준다.  

- 해당 메소드를 사용하기 전에 반드시 배열이 sorted가 되어야한다. 

 

 

📣 comment

함수가 구현되어 있지만, 직접 구현해보면 좋을 것 같아서 구현해보았다.

 

기억해두기

1. start와 end 설정하기. 이 둘을 이용해서 mid값을 계속 업데이트해주면서 값을 찾아나감

2. while의 조건문은 start <= end라는 점!!