intro
๐ง ์์ฐจ ํ์ - ์ ํ ํ์) ๋ฆฌ์คํธ ์์ ์๋ ํน์ ํ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๊ธฐ ์ํด ์์์๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ํ์ธ (๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํํ - ํ ๊ฐ์ฉ ํ์ธ)
๐ง ์ด์ง ํ์) ์ ๋ ฌ๋์ด ์๋ ๋ฆฌ์คํธ์์ ํ์ ๋ฒ์๋ฅผ ์ ๋ฐ์ฉ ์ขํ๊ฐ๋ฉฐ ๋ฐ์ดํฐ๋ฅผ ํ์(์์์ , ๋์ , ์ค๊ฐ์ ์ ์ด์ฉํ์ฌ ํ์ ๋ฒ์ ์ค์ )
โป ์ด์ง ํ์์ ์์ฐจ ํ์์ ๋นํด ํ์ ๋ฒ์๊ฐ ํจ์ฌ ์ค์ด๋ค๊ธฐ ๋๋ฌธ์ ์๊ฐ ๋ณต์ก๋๋ log์๊ฐ์ ๋ณด์ธ๋ค.
Q. ์ด๋ฏธ ์ ๋ ฌ๋ 10๊ฐ์ ๋ฐ์ดํฐ ์ค์์ ๊ฐ์ด 4์ธ ์์๋ฅผ ์ฐพ๊ธฐ
0 - 2 - 4 - 6 - 8 - 10 - 12 - 14 - 16 - 18
โ ์์์ ) index 0, ์ค๊ฐ์ ) index 4, ๋์ ) index 9
→ ์ค๊ฐ์ ์ด 2๊ฐ ์กด์ฌํ๋ค๋ฉด, ์์์ ์ ์ ์ธํ ์๋ถ๋ถ์ ์ค์ ํ๋ค
→ 4๊ฐ ์ค๊ฐ์ ๊ธฐ์ค ์ผ์ชฝ์ ์กด์ฌํจ์ ํ์ธํ๋ฉด, ์ค๊ฐ์ ๊ธฐ์ค ์ค๋ฅธ์ชฝ ํ์ x
โก ์์์ ) index 0, ์ค๊ฐ์ ) index 1, ๋์ ) index 3
→ ์ค๊ฐ์ ๊ธฐ์ค 4๊ฐ ์ค๋ฅธ์ชฝ์ ์กด์ฌํ๋ฏ๋ก, ์ค๊ฐ์ ๊ธฐ์ค ์ผ์ชฝ ํ์ x
โข ์์์ , ์ค๊ฐ์ ) index 2, ๋์ ) index 3
→ ์ค๊ฐ์ ์ ์์นํ ์์๊ฐ ์ฐ๋ฆฌ๊ฐ ์ฐพ๊ณ ์ ํ๋ ์์์์ ์ ์ ์๋ค.
โป ๋จ๊ณ๋ง๋ค ํ์ ๋ฒ์๋ฅผ 2๋ก ๋๋๊ธฐ ๋๋ฌธ์, ์ฐ์ฐํ์๋ $\log_2 N$์ ๋น๋ก
โป ๋ฐ๋ผ์, ์ด์งํ์์ ์๊ฐ๋ณต์ก๋๋ $O(log N)$ โป
binary search python
Q. binary searchํ๋ ์์์ ๊ฐฏ์์ ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ธ target์ ์ ๋ ฅ๋ฐ๋๋ค. ๊ทธ๋ฆฌ๊ณ , target์ด ์กด์ฌํ๋ค๋ฉด, '๋ช ๋ฒ์งธ์ ์กด์ฌ'ํ๋์ง ์ถ๋ ฅ
โ ์ฌ๊ท ๊ตฌํ
def binary_search(array, target, start, end):
if start > end:
return None
mid = (start+end)//2
if array[mid] == target:
return mid #์ค๊ฐ์ ์ด target์ด๋ฉด ๋!
elif array[mid] > target:
return binary_search(array,target,start,mid-1)
else:
return binary_search(array,target,mid+1,end)
n,target=list(map(int,input().split()))
array=list(map(int,input().split()))
result=binary_search(array,target,0,n-1)
if result == None: print('no target found')
else: print(result+1)
โก ๋ฐ๋ณต๋ฌธ ๊ตฌํ
def binary_search(array,target,start,end):
while start<=end:
mid=(start+end)//2
if array[mid] == target: return mid
elif array[mid] > target: end = mid -1
else: start = mid + 1
return None
n,target=list(map(int,input().split()))
array=list(map(int,input().split()))
result=binary_search(array,target,0,n-1)
if result==None: print('no target found')
else: print(result+1)
โ start index <= end index์ธ ๋์ ๊ณ์ ์งํ
ํน์ ์์ ๋น๋ ์ ๊ตฌํ๊ธฐ
(1) binary search๋ฅผ ํ์ฉํ left / right index ๊ฐ๊ฐ ๊ตฌํ๊ธฐ
๐ง ๋จผ์ ์ฃผ์ด์ง ๋ฐฐ์ด์ ์ ๋ ฌํ๊ณ ๋ ๋ค, ์ ๋ ฌ๋ ๋ฐฐ์ด์์ ํน์ ์์๊ฐ ๋ช ๊ฐ ์กด์ฌํ๋ ์ง ์๊ณ ์ถ์ ๋ binary search algorithm์ ์ ์ฉํ ์ ์๋ค. ํน์ ์์๊ฐ ์ผ์ชฝ ๊ธฐ์ค ์ฒซ ๋ฒ์งธ๋ก ๋ฑ์ฅํ๋ index๋ฅผ A๋ผ ํ๊ณ , ์ค๋ฅธ์ชฝ ๊ธฐ์ค ์ฒซ ๋ฒ์งธ๋ก ๋ฑ์ฅํ๋ index + 1์ B๋ผ๊ณ ํ๋ค๋ฉด ํน์ ์์์ ๋น๋์๋ B-A๋ก ์ฝ๊ฒ ๊ตฌํ ์ ์๋ค. ์ด ๋ A์ B๋ฅผ ๊ตฌํ๋ ๊ณผ์ ์ binary search ํ์ฉํ ์ ์๋ค.
์ด ๋, left๋ ๋ง ๊ทธ๋๋ ์ผ์ชฝ ๊ธฐ์ค ์ฒซ๋ฒ์งธ ๋ฑ์ฅ ์์์ index์ด์ง๋ง, right๋ ์ค๋ฅธ์ชฝ ๊ธฐ์ค ์ฒซ๋ฒ์งธ ๋ฑ์ฅ ์์์ index + 1์ด๋ค
๐ง ๊ตฌํ๊ณ ์ ํ๋ ํน์ ์๋ฅผ target์ด๋ผ ํ๊ณ ์ด๋ฏธ ์ ๋ ฌ๋ array๋ฅผ l์ด๋ผ ํ์, A์ B๋ฅผ ๊ฐ๊ฐ left()์ right()๋ก ๊ตฌํ๊ณ ์ ํ๋ค๋ฉด ์๋์ ๊ฐ์ด ๊ตฌํ ์ ์๋ค.
def left(target, l):
st,en=0,len(l)
while st<en:
mid=(st+en)//2
if l[mid]>=target:
en=mid
elif l[mid]<target:
st=mid+1
#when st==en
return st
def right(target, l):
st,en=0,len(l)
while st<en:
mid=(st+en)//2
if l[mid]>target:
en=mid
elif l[mid]<=target:
st=mid+1
#when st==en
return st
โ left()
โ st์ en ๊ฐ๊ฐ index 0 / len(l)์ด๋ผ ํ๋ค. ์ด ๋ , en index๋ฅผ ๋งจ ๋์ ์์ index + 1์ ์ฃผ์(๊ทธ๋์ผ๋ง ๋ฐฐ์ด์ ์์๊ฐ 1๊ฐ ์์ ๋๋ ์ ์ฉ๊ฐ๋ฅ)
โก st < en์ธ ๋์ while๋ฌธ ๋๋ฆผ (st์ en์ด ๊ฐ์ ๋ while๋ฌธ ์ข ๋ฃ)
โข
(1) l[mid] > target๋ผ๋ฉด en์ mid (์๋๋ฉด target์ ์ฐ์๋ ๋ฐฐ์ด์ mid -1 ๊น์ง์ ์์ ์กด์ฌํ๊ณ / ๋ง์ฝ target์ด ์๋ค๋ฉด ์ต๋ mid ๊น์ง ์กด์ฌ)
(2) l[mid] < target๋ผ๋ฉด st๋ฅผ mid+1 (์๋๋ฉด target์ ์ฐ์๋ ๋ฐฐ์ด์ mid + 1๋ถํฐ ๋๊น์ง์ ์กด์ฌํ๊ณ / ๋ง์ฝ target์ด ์๋ค๋ฉด ์ต์ mid + 1๋ถํฐ ์กด์ฌ)
→ Q. en์ mid-1๋ก ํ์ง ์๋ ์ด์
ex) ์๋ฅผ ๋ค์ด ์๋ ๊ทธ๋ฆผ์์ 22๊ฐ ์๋, 23์ left๋ฅผ ์ฐพ๋๋ค๊ณ ํ์. ๊ทธ๋ฌ๋ฉด 23์ left๋ mid์ธ en์ด ๋๋ฏ๋ก, en์ mid๋ก ํญ์ ์ค์ (์ ์ค๋ฅธ์ชฝ index๋ ํญ์ ๋ง์ง๋ง ๋ฑ์ฅ ์์ + 1์ด๊ธฐ ๋๋ฌธ)
(3) l[mid] == target์ด๋ผ๋ฉด left๋ ์ ์ด๋ mid์ index๋ณด๋ค ํฌ์ง๋ ์๊ฒ ๋ค๋ ๊ฑธ ์๊ธฐ ๋๋ฌธ์, ์ฐ๋ฆฌ๋ left๋ฅผ ๊ตฌํ๋ ๊ฒ์ด๋ฏ๋ก ํ์ ๋ฒ์๋ฅผ end๋ฅผ mid๋ก ํด์ mid ๊ธฐ์ค mid ํฌํจ ์ผ์ชฝ ๋ฒ์๋ก ์ ๋ฐ์ผ๋ก ์ค์ผ ์ ์๋ค.
โฃ while๋ฌธ ์ข ๋ฃ๋ ๋๋ st์ en์ด ๊ฐ์ ๋์ด๋ฏ๋ก ๊ทธ ๋ st๊ฐ์ left๊ฐ์ผ๋ก return
โ right()
โ โก ๋ชจ๋ ์ left()์ ๋์ผ
โข
(1) l[mid] > target์ด๋ผ๋ฉด en์ mid
(2) l[mid] < target์ด๋ผ๋ฉด st๋ฅผ mid + 1
(3) l[mid] == target์ด๋ผ๋ฉด right๋ ์ ์ด๋ mid + 1๋ถํฐ ์กด์ฌ. ์ฆ ์ค๋ฅธ์ชฝ ๋ถ๋ถ์ด๋ฏ๋ก ์ left์ ์ด ๋ถ๋ถ๋ง ๋ค๋ฆ
โฃ ์ left()์ ๋์ผ
โป ์๋ ์์ ๊ทธ๋ฆผ array์์ 22๋ฅผ target์ผ๋ก ์ฐพ๋๋ค๊ณ ๊ฐ์ ํ๊ณ ๊ทธ๋ฆผ ์๊ฐํํ๋ฉฐ ์ฝ๋ ์งํํ๋ฉด ์ดํดํ๊ธฐ ํจ์ฌ ์ฝ๋ค
(2) ํจ์ ์ฌ์ฉ bisect_left() / bisect_right()
โ ์ ์ง์ ๊ตฌํํ binary search ์๊ณ ๋ฆฌ์ฆ์ ๋งค์ฐ ์ฝ๊ฒ bisect_left() / bisect_right() ํจ์๋ฅผ ๊ตฌํํด ๋ฐ๋ก ํ ์ ์๋ค.
๐ง bisect_left(a,x): ์ ๋ ฌ๋ ์์๋ฅผ ์ ์งํ๋ฉด์ ๋ฐฐ์ด a์ x๋ฅผ ์ฝ์ ํ ๊ฐ์ฅ ์ผ์ชฝ index ๋ฐํ
๐ง biset_right(a,x): ์ ๋ ฌ๋ ์์๋ฅผ ์ ์งํ๋ฉด์ ๋ฐฐ์ด a์ x๋ฅผ ์ฝ์ ํ ๊ฐ์ฅ ์ค๋ฅธ์ชฝ index ๋ฐํ
from bisect import bisect_left, bisect_right
a = [1,2,4,4,8]
x = 4
print(bisect_left(a, x)) #2
print(bisect_right(a, x)) #4
→ ์ฆ, x๊ฐ ๋ฐฐ์ด a์์ ์ฝ์ ๋ ์ ์๋ ๊ฐ์ฅ ์ต์๊ฐ์ index์ ์ต๋๊ฐ์ index๊ฐ bisect_left์ bisect_right ๊ฒฐ๊ณผ ๋์ค๊ฒ ๋๋ค.
→ bisect_left ๊ฒฐ๊ด๊ฐ: x๊ฐ ๋ค์ด๊ฐ ์ ์๋ ๋ฒ์์ ๋งจ ์ผ์ชฝ ์์ index
→ bisect_right ๊ฒฐ๊ด๊ฐ: x๊ฐ ๋ค์ด๊ฐ ์ ์๋ ๋ฒ์์ ๋งจ ์ค๋ฅธ์ชฝ ์์ '๊ทธ ๋ค์ ์์' index
๐ง ์์ฉํด์, ์๋์ ๊ฐ์ด '๊ฐ์ด ํน์ ๋ฒ์์ ์ํ๋ ๋ฐ์ดํฐ์ ๊ฐ์'๋ฅผ ๊ตฌํ ์๋ ์๋ค.
โ ๊ฐ์ด A์ B ์ฌ์ด(๋ ๋ค ํฌํจ)์ ์๋ ๋ฐ์ดํฐ์ ๊ฐ์๋ฅผ ๊ตฌํ๊ณ ์ถ๋ค๋ฉด bisect_left()์ A / bisect_right()์ B๋ฅผ ๋ฃ์ด B-A๊ฐ ๊ฐ์
from bisect import bisect_left, bisect_right
def count_by_range(a,left_value,right_value):
right_index = bisect_right(a,right_value)
left_index = bisect_left(a,left_value)
return right_index - left_index
a = [1,2,3,3,3,3,4,4,8,9]
#๊ฐ์ด 4์ธ ๋ฐ์ดํฐ ๊ฐ์ ์ถ๋ ฅ
print(count_by_range(a, 4, 4)) #2
#๊ฐ์ด [-1,3] ๋ฒ์์ ์๋ ๋ฐ์ดํฐ ๊ฐ์ ์ถ๋ ฅ
print(count_by_range(a, -1, 3)) #6
* Binary Search ๋ํ ์ ํ ๋ฌธ์ ํ์ด>
Q1. ๋ก๋ณถ์ด ๋ก ๋ง๋ค๊ธฐ
Q. ์ค๋ ๋ผ์ด์ธ์ ์ฌํ ๊ฐ์ ๋ถ๋ชจ๋์ ๋์ ํด์ ๋ก์ง ์ผ์ ํ๊ธฐ๋ก ํ์ต๋๋ค. ์ค๋์ ๋ก๋ณถ์ด ๋ก์ ๋ง๋๋ ๋ ์ ๋๋ค. ๋ผ์ด์ธ๋ค ๋ก๋ณถ์ด ๋ข์ ์ฌ๋ฐ๊ฒ๋ ๋ก๋ณถ์ด ๋ก์ ๊ธธ์ด๊ฐ ์ผ์ ํ์ง ์์ต๋๋ค. ๋์ ์ ํ ๋ด์ง ์์ ๋ค์ด๊ฐ๋ ๋ก์ ์ด ๊ธธ์ด๋ ์ ๋จ๊ธฐ๋ก ์๋ผ์ ๋ง์ถฐ์ค๋๋ค. ์ ๋จ๊ธฐ์ ๋์ด(H)๋ฅผ ์ง์ ํ๋ฉด ์ค์ง์ด์ง ๋ก์ ํ ๋ฒ์ ์ ๋จํฉ๋๋ค. ๋์ด๊ฐ H๋ณด๋ค ๊ธด ๋ก์ H ์์ ๋ถ๋ถ์ด ์๋ฆด ๊ฒ์ด๊ณ , ๋ฎ์ ๋ก์ ์๋ฆฌ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋์ด๊ฐ 19, 14, 10, 17cm์ธ ๋ก์ด ๋๋ํ ์๊ณ ์ ๋จ๊ธฐ ๋์ด๋ฅผ 15cm๋ก ์ง์ ํ๋ฉด ์๋ฅธ ๋ค ๋ก์ ๋์ด๋ 15, 14, 10, 15cm๊ฐ ๋ ๊ฒ์ ๋๋ค. ์๋ฆฐ ๋ก์ ๊ธธ์ด๋ ์ฐจ๋ก๋๋ก 4, 0, 0, 2cm์ ๋๋ค. ์๋์ 6cm๋งํผ์ ๊ธธ์ด๋ฅผ ๊ฐ์ ธ๊ฐ๋๋ค. ์๋์ด ์์ ๋ ์์ฒญํ ์ด ๊ธธ์ด๊ฐ M์ผ ๋ '์ ์ด๋ M'๋งํผ์ ๋ก์ ์ป๊ธฐ ์ํด ์ ๋จ๊ธฐ์ ์ค์ ํ ์ ์๋ ๋์ด์ '์ต๋๊ฐ'์ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ธ์.
โ ์ ๋จ๊ธฐ์ ๋์ด๊ฐ 0์ด์ 10์ต์ดํ์ธ ๋งค์ฐ ํฐ ๋ฒ์์ ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์ ๋จ์ ์ ํ ํ์์ด ์๋, ์ด์ง ํ์์ ์ํํด์ผ ํ๋ค
โก ์ฌ๋ฌ ๊ฒฝ์ฐ์ ์๋ก ๋๋์ด์ ์๋ฆฐ ๋ก์ ๊ธธ์ด ํฉ์ด M๋ณด๋ค ํฐ ์ง, ์๋ ์ง ๋ ๊ฐ์ง ๊ฒฐ๊ณผ ๊ฐ์ง์์ ์ํด ํ์ ๋ฒ์๋ฅผ ๋๋ฆฌ๊ฑฐ๋ ์ค์ผ ์ ์์ผ๋ฏ๋ก ์ด์งํ์ ์ ํ์์ ์ ์ ์๋ค.
โถ ์ฆ, ์๊ฐ์ด ์ง๋ ์๋ก ์ค๊ฐ์ ์ ๊ฐ์ด '์ต์ ํ๋ ๊ฐ'์ผ๋ก ๋ณํ๋ฏ๋ก, ์ด์งํ์์ ์ํํ๋ฉด์ ์ค๊ฐ์ ์ ๊ฐ์ ๊ณ์ updateํ๋ฉด ๋๋ค
n,m=list(map(int,input().split(' ')))
array=list(map(int,input().split()))
start=0
end=max(array)
res=0
while(start<=end):
total=0
mid=(start+end)//2
for x in array:
#์๋์ ๋ ๋ก์ ์
if x > mid:
total+=x-mid
#๋ก์ ์์ด ๋ถ์กฑํ๋ฉด ๋ ๋ง์ด ์๋ฅด๊ธฐ (์ผ์ชฝ ๋ถ๋ถ ํ์)
if total < m:
end=mid -1
#๋ก์ ์์ด ์ถฉ๋ถํ๋ฉด ๋ ์๋ฅด๊ธฐ (์ค๋ฅธ์ชฝ ๋ถ๋ถ ํ์)
else:
res=mid
start=mid+1
#์ต์ข
์ ์ธ res๊ฐ ๊ตฌํ๊ณ ์ ํ๋ ๋ต
print(res)
Q2. ์ ๋ ฌ๋ ๋ฐฐ์ด์์ ํน์ ์์ ๊ฐ์ ๊ตฌํ๊ธฐ
Q. N๊ฐ์ ์์๋ฅผ ํฌํจํ๊ณ ์๋ ์์ด์ด ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌ๋์ด ์๋ค. ์ด๋ ์ด ์์ด์์ x๊ฐ ๋ฑ์ฅํ๋ ํ์๋ฅผ ๊ณ์ฐํ์ธ์. ์๋ฅผ ๋ค์ด ์์ด {1,1,2,2,2,2,3}์ด ์์ ๋ x=2๋ผ๋ฉด, ํ์ฌ ์์ด์์ ๊ฐ์ด 2์ธ ์์๊ฐ 4๊ฐ์ด๋ฏ๋ก 4๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
โป ๋จ, ์ด ๋ฌธ์ ๋ ์๊ฐ๋ณต์ก๋ $O(logN)$์ผ๋ก ์๊ณ ๋ฆฌ์ฆ์ ์ค๊ณํ์ง ์์ผ๋ฉด ์๊ฐ ์ด๊ณผ ํ์ ์ ๋ฐ๋๋ค.
โถ ๋ index์ ์ฐจ์ด๋ก, ์ํ๋ value์ ๋ฒ์ ๋๋, ๊ทธ value๊ฐ ์์ฒด์ ๊ฐ์๋ฅผ ๊ตฌํ ์ ์๋ค.
from bisect import bisect_left, bisect_right
def count_by_range(array,left_value,right_value):
right_index=bisect_right(array,right_value)
left_index=bisect_left(array,left_value)
return right_index-left_index
n,x=map(int,input().split())
array=list(map(int,input().split()))
count=count_by_range(array,x,x)
if count==0: print(-1)
else: print(count)
'Computer Science > Algorithms' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐Dynamic Programming๐ (1) | 2023.01.03 |
---|---|
bitmasking (0) | 2022.12.20 |
understanding pesudo-code of QuickSort (0) | 2022.12.05 |
DFS / BFS (0) | 2022.10.14 |
๐งญRecursion (0) | 2022.09.27 |
๋๊ธ