upperBound && lowerBound --> binary search
๐ ์ด์ง ํ์์์์ lowerBound
์ upperBound
ํจ์ | ์๋ฏธ | ์กฐ๊ฑด | ๋ฐํ๊ฐ |
---|---|---|---|
lowerBound(arr, x) | x ์ด์(โฅ)์ ์ฒซ ์์น | arr[i] >= x | x ๊ฐ ์ฒ์ ๋ํ๋๋ ์์น ๋๋ ๋ค์ด๊ฐ ์์น |
upperBound(arr, x) | x ์ด๊ณผ(>)์ ์ฒซ ์์น | arr[i] > x | x ๋ณด๋ค ํฐ ๊ฐ์ด ์ฒ์ ๋ํ๋๋ ์์น |
์ด ๋ ํจ์๋ ์ ๋ ฌ๋ ๋ฐฐ์ด์์ x
์ ๊ฐ์, ์ฝ์
์์น ๋ฑ์ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์๋๋ก ํด์ฃผ๋ ์ด๋ถ ํ์ ๊ธฐ๋ฐ ๋๊ตฌ์
๋๋ค.
๋ค์ ์ฌ์ง์ int[] my_cards
์ด๋ค
๋ด๊ฐ ๊ฐ๊ณ ์๋ given_numbers๋ฅผ ์๋์ ๊ฐ๋ค๊ณ ๊ฐ์ ํ์
1
int[] given_numbers = {17, 1, 2, 3, 4, -5};
์ฌ๊ธฐ์ given_numbers์ ํด๋น๋๋ ์ซ์์ ๊ฐฏ์๋งํผ ์์๋๋ก ์ถ๋ ฅํ๋ฉด ์ด๋ ์๋์ ๊ฐ์ด ๋์ฌ ๊ฒ์ด๋ค
1
{0, 1, 3, 2, 1, 0}
์ด ๊ทธ๋ฆผ์ ๋ณด๋ฉด target_number == 2์ผ ๋,
lowerBound๋ ์ฒซ ๋ฒ์งธ 2๊ฐ ๋์ค๋ ์ธ๋ฑ์ค์ ์์นํ๊ณ ,
upperBound๋ 2๋ฅผ ์ด๊ณผํ๋ ์ซ์์ธ 3์ ์ฒซ ๋ฒ์งธ ์ธ๋ฑ์ค์ ์์นํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์ด์ฒ๋ผ ๊ฐ ์ซ์์ ๊ฐ์๋ฅผ ๊ตฌํ๊ณ ์ ํ ๋๋ upperBound - lowerBound ์ฐ์ฐ์ ํตํด ์ฝ๊ฒ ๊ณ์ฐํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด target_number == 17์ด๋ผ๋ฉด, lowerBound์ upperBound ๋ชจ๋ ๊ฐ์ด ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ 7์ด๋ผ๋ ๋์ผํ ์์น๋ฅผ ๋ฐํํฉ๋๋ค. ์ฆ,
java ์ฝ๋ ๋ณต์ฌ upperBound - lowerBound = 7 - 7 = 0 ์ด ๋์ด ํด๋น ์ซ์๊ฐ ๋ฐฐ์ด์ ์กด์ฌํ์ง ์์์ ์ ์ ์์ต๋๋ค. ์ด๋ ๊ทธ๋ฆผ์์๋ 17์ด ํฌํจ๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์ ์์ฐ์ค๋ฝ๊ฒ ์ดํดํ ์ ์์ต๋๋ค.
๋ฐฑ์ค 10816 ์ซ์์นด๋2
์ค์ ์ฐ์ต์ผ๋ก ๋ฐฑ์ค ๋ฌธ์ ๋ฅผ ํ์ด๋ด ์๋ค https://www.acmicpc.net/problem/10816
๐ก์์ด๋์ด
๊ฐ์ด ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ, ๋ ๊ฒฝ๊ณ ๋ชจ๋ arr.length๊ฐ ๋์ด
1
upperBound - lowerBound = 0
์ด ์๋์ผ๋ก ์ฑ๋ฆฝ๋๊ฒ ๋ง๋ ๋ค.
์ด๋ฅผ ์ํด ๊ฐ ํจ์์์ res = arr.length๋ก ์ด๊ธฐํํฉ์๋ค.
๐งพ ํ ์คํธ ์์
1
2
3
4
5
6
7
8
9
# ์์ ์
๋ ฅ 2
10
6 3 2 10 10 10 -10 -10 7 3
8
10 17 -5 2 3 4 5 -10
# ์ถ๋ ฅ๊ฒฐ๊ณผ 2
3 0 0 1 2 0 0 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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.util.Arrays;
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());
String[] N_arr = br.readLine().split(" ");
int[] my_cards = str_to_int(N_arr);
Arrays.sort(my_cards);
int M = Integer.parseInt(br.readLine());
String[] M_arr = br.readLine().split(" ");
int[] given_cards = str_to_int(M_arr);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < M ; i++) {
int target_num = given_cards[i];
int upper = upperBound(my_cards, target_num);
int lower = lowerBound(my_cards, target_num);
if (i < M-1) {
sb.append(upper - lower + " ");
}
else {
sb.append(upper - lower);
}
}
System.out.println(sb.toString().trim());
}
public static int upperBound(int[] my_cards, int target_num) {
int left = 0;
int right = my_cards.length - 1;
int res = my_cards.length;
while (left <= right) {
int mid = (left + right) / 2;
if (my_cards[mid] <= target_num) {
left = mid + 1;
}
else if (my_cards[mid] > target_num) {
res = mid;
right = mid - 1;
}
}
return res;
}
public static int lowerBound(int[] my_cards, int target_num) {
int left = 0;
int right = my_cards.length - 1;
int res = my_cards.length;
while (left <= right) {
int mid = (left + right) / 2;
if (my_cards[mid] < target_num) {
left = mid + 1;
}
else if (my_cards[mid] >= target_num) {
res = mid;
right = mid - 1;
}
}
return res;
}
public static int[] str_to_int(String[] arr) {
int[] res = new int[arr.length];
for (int i = 0; i < res.length; i++) {
res[i] = Integer.parseInt(arr[i]);
}
return res;
}
}