In [16]:
1
2
3
4
import sys, os, random
import numpy as np
sys.path.append("/home/swyoo/algorithm")
from utils.verbose import logging_time
Recursive
recursive version은 x
가 array a
안에 존재하지 않는경우
s >= e
에 들어가서 -1
을 return 한다.
not exist case를 recursive로 다루는 문제 연습: Climbing the Leaderboard
In [89]:
1
2
3
4
5
6
7
def bs(a, s, e, x):
if s >= e:
return s if a[s] == x else -1
mid = (s + e) // 2
if a[mid] < x: return bs(a, mid + 1, e, x)
elif a[mid] == x: return mid
else: return bs(a, s, mid -1, x)
In [399]:
1
2
a = sorted(np.random.randint(0, 500, size=15))
a
1
[95, 96, 206, 232, 249, 315, 316, 338, 399, 434, 460, 464, 465, 473, 480]
In [400]:
1
2
3
4
idx = random.randint(0, len(a) - 1)
print("find {}".format(a[idx]))
assert bs(a, 0, len(a) - 1, a[idx]) == idx
print("ans:", idx)
1
2
3
find 399
ans: 8
In [401]:
1
bs(a, 0, len(a) - 1, random.randint(0, 500))
1
-1
Iterative
iterative version에서는 lowerbound, upperbound
를 따로 저장해 놓을 수 있어서
recursive version보다 not exist case를 다루기 수월하다.
In [402]:
1
2
3
4
5
6
7
8
9
10
11
12
13
def bs2(a, s, e, x):
lowerbound = s
upperbound = e
while s <= e:
mid = (s + e) // 2
if a[mid] == x: return mid
if a[mid] < x: s = mid + 1
else: e = mid - 1
# if not present, s = e + 1
if min(s, mid, e) < lowerbound: print("lower than a[{}]={}".format(lowerbound, a[lowerbound]))
elif max(s, mid, e) > upperbound: print("higher than a[{}]={}".format(upperbound, a[upperbound]))
else: print("Not exist, {} is between {} ~ {}".format(x, a[min(s, mid, e)], a[max(s, mid, e)]))
return -1
In [403]:
1
2
3
4
print(a)
k = random.randint(0, 500)
print("pick random number {}".format(k))
bs2(a, 0, len(a) - 1, k)
1
2
3
4
[95, 96, 206, 232, 249, 315, 316, 338, 399, 434, 460, 464, 465, 473, 480]
pick random number 40
lower than a[0]=95
1
-1
Leave a comment