動機
leetcode時被弄過,所以記錄下來
問題
給定一個2d matrix,行與列都已排序好(小到大),在這之中找出是否有指定的數字
1. 暴力
這沒有應用到已排序的特點,O(n^2)
def f(m,target):
for x in m:
for n in x:
if n == target:
return True
return False
2. 分治
表格可以分開,又是表格, 同時分出來的表格都要走過(表格之間不會重疊),最後再一起看有沒有目標,分治!! O(n^1.58)
def f(m,target,i=len(m)//2,j=len(m[0])//2):
if not m:
return False
if m[i][j] == target:
return True
elif m[i][j] < target: # 在右手邊
return f(m[i][j+1:],target) and # 右手邊
f(m[i+1:],target) and # 下面
f([x[j+1:] for x in m[:i]], target) # 上面的右手邊
else: # 在左手邊
return f(m[i][:j],target) and # 左手邊
f(m[:i],target) and # 上面
f([x[:j+1] for x in m[i+1:]], target) # 下面的左手邊
3. saddleback search
還記得two sum時怎麼移動ptr的嗎?
比目標大動右邊(範圍的上限變小),比目標小動左邊(範圍的下限變大)
這裡也可以做出讓
- 範圍的上限變小
- 範圍的下限變大
的操作嗎?
從左下開始,如果
- 太小,往右
- 太大,往上
O(N+M)
def f(m,target):
i = len(m)
j = 0
while 0 <= i and j < len(m[0]):
if m[i][j] == target:
return True
elif m[i][j] > target:
i -= 1
else:
j += 1
return False
TODO
在functional pearl中其實有一篇說到怎麼從 分治 推到 saddleback search,但之後有時間再來看