题目均采用python进行完成
供暖设备
已知供暖设备和房屋的位置,给出供暖设备的最小半径
注意:供暖设备需要排序
可以使用python中的bisect找到需要插入的索引值
from bisect import bisect
def find_radius(house, heater):
# 供暖设备排序
heater.sort()
radius = 0
# 每个房子寻找最小的供暖距离
for h in house:
index_h = bisect(heater, h)
left = heater[index_h-1] if index_h - 1 >= 0 else float('-inf')
right = heater[index_h] if index_h < len(heater) else float('-inf')
radius = max(radius, min(h - left, right - h))
return radius
sqrt(x)
采用逼近的方法 == 二分查找
def sqrt(x):
left, right = 0, x
while left <= right:
mid = left + (right - left) // 2
if (mid == x // mid):
return mid
elif (mid < x // mid):
left = mid + 1
else:
right = mid - 1
return right
矩阵搜索
在一个N*M的矩阵中,每一行都是排好的,每一列都是排好的,设计一个算法在矩阵中查找一个数
查找最小的搜索方向开始
def matrix_search(matrix, target):
row, col = len(matrix), len(matrix[-1])
left = matrix[row-1][0]
point_left = 0
point_right = row-1
while point_left <= col and point_right >= 0:
if target == left:
return (point_right,point_left)
elif target > left:
point_left += 1
left = matrix[point_right][point_left]
else:
point_right -= 1
left = matrix[point_right][point_left]
return (-1,-1)
矩阵搜索
在一个N*M的矩阵里,每一行和每一列都是排好序的,设置一个算法在矩阵中查找第k小的数字。
思路:找到最小、最大和中间值
中间值在每一行进行二分比较,并求和
小于k,从说明 最小值太小
大于k, 最大值太大 需要重新逼近
from bisect import bisect
def ksmall_search(matrix, k):
left, right = matrix[0][0], matrix[-1][-1]
while left < right:
mid = left + (right - left) // 2
if sum(bisect(row, mid) for row in matrix) < k:
left = mid + 1
else:
right = mid
return left
寻找重复的数字
采用二分搜索的逼近的思想
def find_duplicate(num):
low = 1
high = len(num) - 1
while low < high:
mid = low + (high - low)//2
count = 0
for i in num:
if i <= mid:
count += 1
if count <= mid:
low = mid + 1
else:
high = mid
return low
合并区间
输入[1,3],[2,6],[8,10]
输出[1,6],[8,10]
先写一个建立区间的类
class Interval:
def __init__(self, s=0, e=0):
self.start = s
self.end = e
def __str__(self):
return "[" + self.start + "," + self.end + "]"
def __repr__(self):
return "[%s, %s]" % (self.start, self.end)
再写合并区间
三种情况, 完全包含, 没有交叉, 有小部分交叉
def merge(interval):
inverval.sort(key=lambda x: x.start)
merged = []
for i in interval:
if not merged or merge[-1].end < interval.start:
merged.append(interval)
else:
merged[-1].end = max(merged[-1].end, interval.end)
return merged
插入区间
讨论情况与合并区间类似
def insert(interval, newinterval):
merge = []
for i in interval:
if newinterval is None or i.end < newinterval.start:
merge += i
elif i.start > newinterval.start:
merge += newinterval
merge += i
newinterval = None
else:
newinterval.start = min(i.start, newinterval.start)
newinterval.end = max(i.end, newinterval.end)
if newinterval is not None:
merge += newinterval
return merge