[백준] 1920번 : 수 찾기 - JAVA

2024. 3. 17. 16:41·백준

1920 수 찾기

 

이 문제는 M개의 수가 각각 A 배열에 들어있는 지 확인하는 문제이다.

 

M개의 수가 최대 100,000개이고 시간제한은 1초이기 때문에 정렬 후 이진탐색 알고리즘을 사용하면 된다고 생각하였다.

이진탐색의 시간복잡도는 $ \log_2 N $ 이다.

 

$ 2^{16} = 65,536 $

$ 2^{17} = 131,072 $

$ 16 < \log_2 100000 < 17 $

 

 

이진탐색 구현

private static int[] arrSearch;

private static int binarySearch(int num) {
    int left = 0;
    int right = arrSearch.length - 1;

    while(left <= right) {
        int mid = (left + right) / 2;

        if (arrSearch[mid] > num) {
            right = mid - 1;
        } else if (arrSearch[mid] < num) {
            left = mid + 1;
        } else {
            return 1;
        }
    }

    return 0;
}

 

 

위 소스를 제출하고 다른 사람들은 어떻게 구현했는 지 궁금해서 찾아보다가 Stranger's LAB님의 블로그를 보게 되었다.

 

https://st-lab.tistory.com/261

 

[백준] 1920번 : 수 찾기 - JAVA [자바]

https://www.acmicpc.net/problem/1920 1920번: 수 찾기 첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음

st-lab.tistory.com

 

 

간단한 이진탐색의 문제여서 소스는 거의 동일하였지만 Stranger's LAB님 덕분에 현재 일 하면서 잘 사용하지 않는 비트연산자를 사용해도 된다는 점을 알게 되었다.

 

int mid = (left + right) / 2;
int mid = (left + right) >>> 1;

 

 

비트연산자 종류: <<, >>, >>>

Integer 정수형 32bit 기준으로 설명하겠다.

비트연산자

 

  • << : 2 << 3의 경우 이진수를 3칸 앞으로 이동한다. $ 2 * 2^3 $
  • >> : 16 >> 3의 경우 이진수를 3칸 뒤로 이동하고 최상위 부호 비트로 빈칸을 채운다. $ 16 / 2^3 $ 
  • >>> : 최상위 부호 비트와 상관없이 뒤로 이동한다.

위 이미지만 봤을 때 비트연산자를 사용하며 주의해야 할 점은 4번째 이미지의 경우로, 피연산자가 음수인데 최상위 부호 비트와 상관없이 뒤로 이동하는 >>> 연산자를 사용한 것이다.

 

다시 돌아와 아래 소스는 비트연산자를 적용한 구현 소스이다.

 

성공 소스

public class _1920 {

    private static int[] arrSearch;

    private static int binarySearch(int num) {
        int left = 0;
        int right = arrSearch.length - 1;

        while(left <= right) {
            int mid = (left + right) >>> 1;

            if (arrSearch[mid] > num) {
                right = mid - 1;
            } else if (arrSearch[mid] < num) {
                left = mid + 1;
            } else {
                return 1;
            }
        }

        return 0;
    }

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;

        // 입력 시작
        int n = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());
        arrSearch = new int[n];

        for (int i = 0; i < n; i++) {
            arrSearch[i] = Integer.parseInt(st.nextToken());
        }

        int m = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());
        int[] b = new int[m];

        for (int i = 0; i < m; i++) {
            b[i] = Integer.parseInt(st.nextToken());
        }
        // 입력의 끝

        // 이분탐색 전 정렬
        Arrays.sort(arrSearch);

        // 이분탐색
        for (int i = 0; i < m - 1; i++) {
            sb.append(binarySearch(b[i])).append("\n");
        }
        sb.append(binarySearch(b[b.length - 1]));

        System.out.println(sb);
        br.close();
    }

}

 

 

잠깐 다른 이야기로 위 소스에서 사용한 정렬 Arrays.sort 메소드는 내부적으로 원시타입의 경우 듀얼피봇퀵정렬 알고리즘을 사용하고 있다던데, 추후 공부를 해야겠다.

참조타입의 경우는 Collections.sort와 동일하게 팀정렬 알고리즘을 사용한다.

 

 

feat. 정렬 알고리즘 종류

/**
 * 정렬
 * 1. 계수 정렬 (Counting Sort)
 * 2. 선택 정렬 (Selection Sort)
 * 3. 삽입 정렬 (Insertion Sort)
 * 4. 거품 정렬 (Bubble Sort)
 * 5. 셸 정렬 (Shell Sort)
 * 6. 힙 정렬 (Heap Sort)
 * 7. 합병(병합) 정렬 (Merge Sort)
 * 8. 퀵 정렬 (Quick Sort)
 * 9. 이진 삽입 정렬 (Binary Insertion Sort)
 * 10. 팀 정렬 (Tim Sort)
 *
 */

 

 

 

- 참고

https://coding-factory.tistory.com/521

 

[Java] 비트(Shift) 연산자 사용법 & 예제

비트 연산자는 데이터를 비트 단위로 연산합니다. 그러므로 0과 1로 표현이 가능한 정수 타입이나 정수형으로 캐스팅이 가능한 자료형만 비트 연산이 가능합니다. 비트 연산자는 기능에 따라 비

coding-factory.tistory.com

저작자표시 비영리 변경금지 (새창열림)

'백준' 카테고리의 다른 글

[백준] 11561번 : 징검다리 - JAVA  (0) 2024.03.31
[백준] 1966번 : 프린터 큐- JAVA  (0) 2024.03.28
[백준] 골드 달성 후기  (0) 2024.03.24
[백준] 1654번 : 랜선 자르기 - JAVA  (0) 2024.03.19
[백준] 11050번 : 이항 계수 1 - JAVA  (2) 2024.03.16
'백준' 카테고리의 다른 글
  • [백준] 1966번 : 프린터 큐- JAVA
  • [백준] 골드 달성 후기
  • [백준] 1654번 : 랜선 자르기 - JAVA
  • [백준] 11050번 : 이항 계수 1 - JAVA
masjeong
masjeong
교양이란 화를 내지 않으면서도 자신의 신념을 잃지 않은 채 어떤 얘기라도 들을 수 있는 능력을 말한다 - 로버트 프로스트
  • masjeong
    나자바바라쿠배
    masjeong
  • 전체
    오늘
    어제
    • 전체보기 (28)
      • Spring Boot (3)
      • Spring Batch (1)
      • MSA (3)
      • Docker (1)
      • 백준 (16)
      • 자료구조 (3)
      • Kafka (0)
      • DB (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    15829
    진법변환
    이진탐색
    백준3041
    spring cloud Gateway
    executortype
    mariadb
    11561
    백준11723
    spring batch
    알고리즘
    gradle 오류
    springboot
    ExecutionContext
    2449
    Cloud Native Architecture
    백준
    이분탐색
    MSA
    SpringCloud
    18110
    cloud native application
    큐
    Queue
    ratelimiter
    18111
    정렬
    티스토리챌린지
    Java
    오블완
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
masjeong
[백준] 1920번 : 수 찾기 - JAVA
상단으로

티스토리툴바