포슀트

Binary-Search

Binary-Search

이진탐색, 이뢄탐색.
μ •λ ¬λœ λ¦¬μŠ€νŠΈμ— λŒ€ν•΄, νŠΉμ • μ›μ†Œλ₯Ό Log N μ•ˆμ— μ°Ύμ•„λ‚΄λŠ” μ•Œκ³ λ¦¬λ“¬

πŸ’« Use


  • Data-Structure-Binary-Search-Tree

  • μ „ν™”λ²ˆν˜ΈλΆ€μ—μ„œ 이름이 K둜 μ‹œμž‘ν•˜λŠ” μ‚¬λžŒμ˜ 번호 μ°ΎκΈ°
    • μ±… ν•œκ°€μš΄λ°λ₯Ό 펼치고 μ°ΎκΈ° μ‹œμž‘ν•˜λŠ” 방법
      • μ•ŒνŒŒλ²³ μˆœμ„œλŒ€λ‘œλΌλ©΄ 쀑간쯀에 K둜 μ‹œμž‘ν•˜λŠ” 이름이 μžˆμ„ ν…Œλ‹ˆκΉŒ
  • μ‚¬μ „μ—μ„œ 단어 μ°ΎκΈ°
  • νŽ˜μ΄μŠ€λΆμ— λ‘œκ·ΈμΈν•˜κΈ° (페이슀뢁이 λ‚΄ 계정이 μ‹€μ‘΄ν•˜λŠ” 계정인지 ν™•μΈν•˜κΈ° μœ„ν•΄ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 아이디 μ°ΎκΈ°)

πŸ’« μ™œ Why


Updown κ²Œμž„.
μ²˜μŒλΆ€ν„° λκΉŒμ§€ 숫자 ν•˜λ‚˜ν•˜λ‚˜ μˆœμ„œλŒ€λ‘œ κ²€μ¦ν•˜λŠ” 것 λ³΄λ‹€λŠ”, 더 쒋은 방법.

νƒμƒ‰μ‹œκ°„μ„€λͺ…
μ„ ν˜•νƒμƒ‰O(n)리슀트의 μ²˜μŒλΆ€ν„° λκΉŒμ§€ 순차적으둜 탐색
이진탐색O(log n)μ •λ ¬λœ λ¦¬μŠ€νŠΈμ—μ„œ 탐색 λ²”μœ„λ₯Ό μ ˆλ°˜μ”© 쀄여가며 탐색
  • λ¦¬μŠ€νŠΈμ— 숫자 N개 μžˆλ‹€λ©΄
    • μ„ ν˜•νƒμƒ‰: μ΅œμ•…μ˜ 경우 N개의 숫자λ₯Ό λͺ¨λ‘ 확인해야 함.
    • 이진탐색: μ΅œμ•…μ˜ 경우 logN만 ν™•μΈν•˜λ©΄ 됨.
  • if N = 1,024
    • μ„ ν˜•νƒμƒ‰: μ΅œμ•…μ˜ 경우 1,024
    • 이진탐색: μ΅œμ•…μ˜ 경우 log21,024 = 10

πŸ’« κ΅¬ν˜„


🫧 μ°ΎλŠ” 값이 ν•˜λ‚˜

low/high (or start/end).
찾고자 ν•˜λŠ” 값이 ν¬ν•¨λ˜μ–΄ μžˆμ„ 거라고 μ˜ˆμƒν•˜λŠ” λ²”μœ„.
(값이 리슀트 μžμ²΄μ— 없을 μˆ˜λ„ 있기 λ•Œλ¬Έμ— μ˜ˆμƒ λ²”μœ„)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int binarySearch(int arr[], int target, int size)
{
	// μ²˜μŒμ—λŠ” λͺ¨λ“  λ²”μœ„λ₯Ό 탐색
	int low = 0;
	int high = size - 1;

	// μ„œλ‘œ μœ„μΉ˜κ°€ μ—­μ „λ˜λ©΄, μ˜ˆμƒ λ²”μœ„κ°€ μ—†λ‹€λŠ” 것.
	while (low <= high)
	{
		// μ ˆλ°˜μ”© λ²”μœ„λ₯Ό 쀄여 λ‚˜κ°€λŠ”
		// ν™€μˆ˜μΌ κ²½μš°μ—λŠ” λ‚΄λ¦Ό
		int mid = (low + high) / 2;

		if (arr[mid] == target)
			return mid;
		else if (arr[mid] < target)
			low = mid + 1;
		else
			high = mid - 1;
	}

	return -1;
}

🫧 μ°ΎλŠ” 값이 μ—¬λŸ¬ 개

이뢄 탐색 ν›„ 찾은 μœ„μΉ˜μ—μ„œ μ–‘ μ˜†μœΌλ‘œ ν™•μž₯해도 λ˜μ§€λ§Œ,
μ΅œμ•…μ˜ 경우 O(N)이 될 수 있음. (μ „λΆ€ λ‹€ 같은 값일 경우)

λŒ€μ‹ ,
κ°€μž₯ λ§ˆμ§€λ§‰μ— λ‚˜μ˜€λŠ” κ°’μ˜ 인덱슀 - κ°€μž₯ λ¨Όμ € λ‚˜μ˜€λŠ” κ°’ 인덱슀 + 1 = 개수

λ‹€λ₯΄κ²Œ μƒκ°ν•˜λ©΄,
찾고자 ν•˜λŠ” 값을 μ‚½μž…ν–ˆμ„ λ•Œ μ˜€λ¦„μ°¨μˆœμ΄ μœ μ§€λ˜λŠ” μœ„μΉ˜λ₯Ό μ°ΎλŠ” 것.
μ˜€λ¦„μ°¨μˆœμ΄ μœ μ§€λ˜λŠ” κ°€μž₯ 였λ₯Έμͺ½ μœ„μΉ˜ - μ˜€λ¦„μ°¨μˆœμ΄ μœ μ§€λ˜λŠ” κ°€μž₯ μ™Όμͺ½ μœ„μΉ˜ = 개수

λ°”ν‚Ήλ…λ‹˜ 이미지

κ°€μž₯ λ¨Όμ € λ‚˜μ˜€λŠ” κ°’μ˜ 인덱슀
= μ‚½μž…ν–ˆμ„ λ•Œ μ˜€λ¦„μ°¨μˆœμ΄ μœ μ§€λ˜λŠ” κ°€μž₯ μ™Όμͺ½ μœ„μΉ˜.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int lowerBound(int arr[], int target, int size)
{
	int low = 0;
	int high = size;

	while (low < high)
	{
		int mid = (low + high) / 2;

		if (arr[mid] >= target)
			high = mid;
		else
			low = mid + 1;
	}

	return low;
}

λ°”ν‚Ήλ…λ‹˜ 이미지

κ°€μž₯ λ§ˆμ§€λ§‰μ— λ‚˜μ˜€λŠ” κ°’μ˜ 인덱슀
= μ‚½μž…ν–ˆμ„ λ•Œ μ˜€λ¦„μ°¨μˆœμ΄ μœ μ§€λ˜λŠ” κ°€μž₯ 였λ₯Έμͺ½ μœ„μΉ˜.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int upperBound(int arr[], int target, int size)
{
	int low = 0;
	int high = size;

	while (low < high)
	{
		int mid = (low + high) / 2;

		if (arr[mid] > target)
			high = mid;
		else
			low = mid + 1;
	}

	return low;
}

πŸ’« λ©”λͺ¨


  • C++ STL
    • binary_search ν•¨μˆ˜
      • λ¦¬μŠ€νŠΈκ°€ λ°˜λ“œμ‹œ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬λ˜μ–΄ μžˆμ–΄μ•Ό 함.
      • μš”μ†Œ 유무λ₯Ό true/false둜 λ°˜ν™˜
    • lower_bound ν•¨μˆ˜
      • 찾고자 ν•˜λŠ” κ°’ 이상이 처음 λ‚˜νƒ€λ‚˜λŠ” μœ„μΉ˜
    • upper_bound ν•¨μˆ˜
      • 찾고자 ν•˜λŠ” κ°’ μ΄ˆκ³Όκ°€ 처음 λ‚˜νƒ€λ‚˜λŠ” μœ„μΉ˜
    • equal_range ν•¨μˆ˜
      • lower_bound와 upper_boundλ₯Ό ν•œ λ²ˆμ— 호좜
      • pair둜 λ°˜ν™˜
  • Parametric Search 처럼 STLκ°€ 도움이 μ•ˆλ˜κ³  직접 이뢄탐색을 ν•΄μ•Όν•˜λŠ” κ²½μš°κ°€ μžˆλ‹€.
    • λ¬΄ν•œ 루프에 λΉ μ§€λŠ” κ²½μš°κ°€ 있기 λ•Œλ¬Έμ— 주의
  • λ¬΄ν•œ 루프에 빠지지 μ•ŠμœΌλ €λ©΄
    • μ˜€λ²„ν”Œλ‘œμš° 방지: int mid = low + (high - low) / 2;
    • κ· λ“±ν•˜κ²Œ λ‚˜λˆ„κΈ°: mid = (high - low + 1) / 2;
  • TODO: μ’Œν‘œ μ••μΆ• ~
이 κΈ°μ‚¬λŠ” μ €μž‘κΆŒμžμ˜ CC BY 4.0 λΌμ΄μ„ΌμŠ€λ₯Ό λ”°λ¦…λ‹ˆλ‹€.