每日编程题 11

题目均采用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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值