07
16

โ–ถ ์œ ํ˜•

  • ์ด์ง„ํƒ์ƒ‰์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ˜์œผ๋กœ ๊ณ„์† ๋ฒ”์œ„๋ฅผ ์ชผ๊ฐœ๊ฐ€๋ฉฐ ํƒ€๊ฒŸ ๊ฐ’์„ ์ฐพ๋Š” ๊ธฐ๋ฒ•์ด๋‹ค. ๊ทธ๋ž˜์„œ ์ˆœ์ฐจํƒ์ƒ‰์ด `O(n)` ๊ฑธ๋ฆด ๋•Œ ์ด์ง„ํƒ์ƒ‰์€ `O(logN)`์ด ๋œ๋‹ค.
  • ๊ทผ๋ฐ ์ •๋ ฌ๋œ ์ƒํƒœ๋ฅผ ์ „์ œ๋กœ ๋‘”๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” `O(NlogN)`์ด๋‹ค. 
  • ์–‘ ๋์„ L, R๋กœ ๋‘๊ณ , L๊ณผ R์˜ ์ˆœ์„œ๊ฐ€ ์—ญ์ „๋˜๋Š” ์ˆœ๊ฐ„์ด ์ข…๋ฃŒ ์กฐ๊ฑด์ด๋‹ค.
  • ๊ฒฐ์ • ์กฐ๊ฑด์„ ๊ฐ€์ง€๋Š” ์ตœ์ ํ™” ๋ฌธ์ œ์ธ ํŒŒ๋ผ๋ฉ”ํŠธ๋ฆญ ์„œ์น˜์˜ ๊ฒฝ์šฐ์—๋Š”, L์€ ์ •๋‹ต์ด ์•ˆ๋ผ์„œ ๊ณ„์† ์˜ฌ๋ผ๊ฐ€๊ณ , R์€ ์ •๋‹ต์ด ๋์Œ(์ •๋‹ต์ด ์•„๋‹ ์ˆ˜ ๋„ ์žˆ์Œ)์—๋„ ๋” ์ตœ์ ์ธ ๋‹ต์ด ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์„ ๋‘๊ณ  ๋‚ด๋ ค๊ฐ„๋‹ค.

๊ธฐ๋ณธ์ ์ธ ํ˜•ํƒœ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

public static int binarySearch(int[] arr, int target) {
    int left = 0;
    int right = arr.length - 1;

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

        if (arr[mid] == target) {
            return mid; // ์ฐพ์€ ๊ฒฝ์šฐ ์ธ๋ฑ์Šค ๋ฐ˜ํ™˜
        }

        if (arr[mid] < target) {
            left = mid + 1; // ์ค‘๊ฐ„๊ฐ’๋ณด๋‹ค ํฌ๋ฉด ์˜ค๋ฅธ์ชฝ ์ ˆ๋ฐ˜ ํƒ์ƒ‰
        } else {
            right = mid - 1; // ์ค‘๊ฐ„๊ฐ’๋ณด๋‹ค ์ž‘์œผ๋ฉด ์™ผ์ชฝ ์ ˆ๋ฐ˜ ํƒ์ƒ‰
        }
    }

    return -1; // ์ฐพ์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ
}

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐ–๋‹ค๊ฐ€ ์“ฐ๋ฉด `Arrays.binarySearch()`๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ์ˆœํ•œ ์ด์ง„ํƒ์ƒ‰์€ ์–ด๋ ต์ง€ ์•Š๋‹ค. ๋‚ด๊ฐ€ ์ฒ˜์Œ ์ด์ง„ํƒ์ƒ‰์—์„œ ์–ด๋ ค์›€์„ ๋Š๊ผˆ๋˜ ๊ฑด lower bound, upper bound์˜€๋‹ค.

#Lower Bound, Upper Bound

์–˜๋Š” ๋ณดํ†ต ์–ธ์ œ ์“ฐ๋ƒ ํ•˜๋ฉด, ์ค‘๋ณต๋œ ๊ฐ’์ด ๋ฐฐ์—ด์— ์กด์žฌํ•˜๊ณ , ์–ด๋–ค ์œ„์น˜์—์„œ ์ฐพ๊ฒŒ ๋  ์ง€ ๋ชจ๋ฅด๋Š” ์ƒํ™ฉ์— ์‚ฌ์šฉํ•œ๋‹ค. lower bound๋Š” ํƒ€๊ฒŸ ๊ฐ’ ์ด์ƒ์˜ ๊ฐ’์ด ์ตœ์ดˆ๋กœ ๋‚˜์˜ค๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•˜๊ณ , upper bound๋Š” ๊ทธ ๋ฐ˜๋Œ€๋‹ค.

 

์ฆ‰ lower bound๋Š” ํƒ€๊ฒŸ ๊ฐ’๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํฐ ์›์†Œ ์ค‘ ๊ฐ€์žฅ ์œ„์น˜๊ฐ’์ด ์ž‘์€ ๊ฐ’์„ ์ฐพ๋Š” ๊ฒฝ์šฐ๋‹ค.

public static int lowerBound(List<Integer> arr, int target) {
    int left = 0;                  
    int right = arr.size() - 1;    
    int idx = arr.size();       // ์ตœ์†Œ์œ„์น˜์ด๋ฏ€๋กœ, ๋‹ต์ด ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ’๋ณด๋‹ค ๋” ํฐ ๊ฐ’์œผ๋กœ ์„ค์ •(min max ๊ฐœ๋…)

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

        if (arr.get(mid) >= target) {  // ๋งŒ์•ฝ์— ์„ ํƒํ•œ ์›์†Œ๊ฐ€ target๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํฌ๋‹ค๋ฉด
            right = mid - 1;           // ์™ผ์ชฝ์— target์ด ๋” ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ right ๊ฐฑ์‹ 
            idx = Math.min(idx, mid);  // ์ตœ์†Œ ์œ„์น˜๊ฐ’(lower bound) ๊ณ„์† ๊ฐฑ์‹ 
        } else {
            left = mid + 1;            // ํƒ€๊ฒŸ๋ณด๋‹ค ์ž‘์œผ๋ฉด left ๊ฐฑ์‹ 
        }
    }

    return idx;
}

upper bound๋Š” ๊ทธ ๋ฐ˜๋Œ€์ธ ์ดˆ๊ณผ๊ฐ€ ๋˜๋Š” ์ˆœ๊ฐ„์„ ์ฐพ์œผ๋ฉด ๋˜๋Š”๋ฐ, `arr.get(mid) > target`์œผ๋กœ ๋ฐ”๊พธ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.

์ž˜ ์ƒ๊ฐํ•ด๋ณด๋ฉด lower bound ์™€ upper bound์˜ idx ์ฐจ์ด ๊ฐ’์€ ๊ทธ ํƒ€๊ฒŸ ๊ฐ’์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ฐจ์ด๊ฐ€ 0์ด๋ผ๋ฉด ํ•ด๋‹น ๊ฐ’์ด ๋ฐฐ์—ด์— ์—†๋‹ค๋Š” ๊ฑธ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

# ํŒŒ๋ผ๋ฉ”ํŠธ๋ฆญ ์„œ์น˜

๊ฒฐ์ •๋ฌธ์ œ๋ผ๋Š” ๊ฑธ ๊ฐ–๊ณ , ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์ตœ์†Œ/์ตœ๋Œ€๊ฐ’์„ ๊ตฌํ•˜๋Š” ๋„๊ตฌ๋‹ค.

https://www.acmicpc.net/problem/2805

 

๋ฐฑ์ค€ ๋‚˜๋ฌด์ž๋ฅด๊ธฐ ๋ฌธ์ œ๋ฅผ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ณด๊ฒ ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋•Œ, 2๊ฐ€์ง€๋กœ ๋ถ€๋ถ„์„ ๋‚˜๋ˆ ์„œ ์ž‘์—…ํ•œ๋‹ค.

// ํŠน์ • ๋†’์ด๋กœ ๋‚˜๋ฌด๋“ค์„ ์ž˜๋ž์„ ๋•Œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ด ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜
private static long namuCalculateCutLength(int height) {
    long sum = 0;
    for (int tree : trees) { // trees๋Š” ๋ฐฐ์—ด
        if (tree > height) {
            sum += tree - height;
        }
    }
    return sum;
}

๋‚˜๋ฌด๋ฅผ ๊ณ„์† ์ž๋ฅด๋ฉด์„œ ํ•ฉ์„ ๊ตฌํ•˜๊ณ  ์ด์ง„ํƒ์ƒ‰์˜ ์กฐ๊ฑด์œผ๋กœ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค.

public static int namuCut() {
    int l = 0;
    int r = len; // ๊ฐ€์žฅ ๋†’์€ ๋‚˜๋ฌด์˜ ๋†’์ด

    while (l <= r) {
        int mid = (l + r) / 2;
        
        if (namuCalculateCutLength(mid) >= m) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }

    return end;
}

์ด ๋ฌธ์ œ๋Š” ๊ฒฐ์ • ์กฐ๊ฑด์— L์„ ๋‹ค๋ฃฌ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๊ฒฐ๊ตญ ์ตœ๋Œ€๊ฐ’์„ ๊ตฌํ•ด์•ผ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ตœ์†Œ๊ฐ’์„ ๊ตฌํ•  ๋•Œ๋Š” R์„ ๋‹ค๋ฃจ๊ณ , ์ด๋ฒˆ ๋ฌธ์ œ์ฒ˜๋Ÿผ ์ตœ๋Œ€๊ฐ’์„ ๋‹ค๋ฃฐ ๋•Œ๋Š” L์„ ๊ฒฐ์ •์กฐ๊ฑด์˜ ์‘๋‹ต์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ๋œ๋‹ค. 

โ–ถ ์ „๋žต

์ด์ œ ๋ฌธ์ œ๋ฅผ ํ’€์–ด๋ณด๋ฉด์„œ ์ต์ˆ™ํ•ด์ ธ๋ณด์ž.

https://www.acmicpc.net/problem/10815

 

์ด์ง„ ํƒ์ƒ‰ ๊ทธ ์ž์ฒด์ธ ๋ฌธ์ œ๋‹ค.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    static int n, m;
    static int sanggun[];
    static int find[];
    static StringBuilder sb;

    public static void main(String[] args) throws Exception {
        System.setIn(new FileInputStream("res/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;
        st = new StringTokenizer(br.readLine(), " ");
        n = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine(), " ");
        sanggun = new int[n];
        for (int i = 0; i < n; i++) {
            sanggun[i] = Integer.parseInt(st.nextToken());
        }
        st = new StringTokenizer(br.readLine(), " ");
        m = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine(), " ");
        find = new int[m];
        for (int i = 0; i < m; i++) {
            find[i] = Integer.parseInt(st.nextToken());
        }
        // ํƒ์ƒ‰์„ ์œ„ํ•œ ์ •๋ ฌ
        Arrays.sort(sanggun);
        sb = new StringBuilder();
        for (int i = 0; i < m; i++) {
            sb.append(isExist(find[i])).append(" ");
        }
        System.out.println(sb);
    }

    public static int isExist(int t) {
        int l = 0;
        int r = n - 1; // ์–‘ ๋๊ฐ’ ์„ธํŒ…
        while (l <= r) {
            int m = (l + r) / 2;
            if (sanggun[m] == t) {
                return 1;
            }
            if (sanggun[m] > t) {
                r = m - 1;
            } else {
                l = m + 1;
            }
        }
        return 0;
    }
}

 

 

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”!
๋ฐ˜์‘ํ˜•
COMMENT