力扣——LCP 37. 最小矩形面积(困难)

刚看到本题时感觉难度不是很大,却出现在困难组里面。后面万万没想到提交测试的时候输入了将近20000条直线进行判断,如果直接上来就做的话,那肯定会:
在这里插入图片描述

接下来看题目:

题目

在这里插入图片描述

python代码

刚开始我的代码是直接做的,结果超时。

def minRecSize(lines):
    """
    :type lines: List[List[int]]
    :rtype: float
    """
    x_list=[]
    y_list=[]
    for i in range(len(lines)):
        for j in range(i + 1, len(lines)):
            k1, b1 = lines[i]
            k2, b2 = lines[j]
            if k1 != k2:
                x = (b2 - b1) / (k1 - k2)
                y = ((b2 - b1) / (k1 - k2)) * k1 + b1
                x_list.append(x)
                y_list.append(y)

    if len(x_list)<2:
        return 0
    x_list.sort()
    y_list.sort()
    wideth=x_list[-1]-x_list[0]
    longth=y_list[-1]-y_list[0]
    area=wideth*longth
    # print(x_list)
    # print(y_list)
    # print(area)
    return area

原因就是我的做法将所有斜率不同的线两两求交点,这样的排列组合在两万条线的情况下……

在这里插入图片描述
所以要先处理输入的数据,做法:将所有斜率相同的直线,保留截距最大和最小的那两条,处理所有的直线,将处理后的结果存到新的list中作为上面代码的输入。

def deal(lines):
    k_dict={
    
    }
    new_lines=[]
    for k,b in lines:
        print(k,b)
        if k in k_dict:
            k_dict[k][0]=min(k_dict[k][0],b)
            k_dict[k][1]=max(k_dict[k][1],b)
        else:
            k_dict[k]=[b,b]
    print(k_dict)
    for key,val in k_dict.items():
        new_lines1=[]
        new_lines2=[]
        k=key
        b1=val[0]
        b2=val[1]
        new_lines1.append(k)
        new_lines1.append(b1)
        new_lines2.append(k)
        new_lines2.append(b2)
        if new_lines1 not in new_lines:
            new_lines.append(new_lines1)
        if new_lines2 not in new_lines:
            new_lines.append(new_lines2)
    # print(len(new_lines))
    return new_lines

def minRecSize(lines):
    new_lines=deal(lines)
    print(new_lines)
    x_list=[]
    y_list=[]
    for i in range(len(new_lines)):
        for j in range(i + 1, len(new_lines)):
            k1, b1 = new_lines[i]
            k2, b2 = new_lines[j]
            if k1 != k2:
                x = (b2 - b1) / (k1 - k2)
                y = ((b2 - b1) / (k1 - k2)) * k1 + b1
                x_list.append(x)
                y_list.append(y)

    if len(x_list)<2:
        return 0
    x_list.sort()
    y_list.sort()
    wideth=x_list[-1]-x_list[0]
    longth=y_list[-1]-y_list[0]
    area=wideth*longth
    return area

继续超出时间限制
在这里插入图片描述
接着看到别人更简洁的代码,思路一致,但是省去了一些比较、排序所费的时间

def minRecSize(self, lines: List[List[int]]) -> float:
    if len(lines) <= 2:
        return 0
    dic = {
    
    }
    for k, b in lines:
        if k in dic:
            dic[k][0] = min(dic[k][0], b)
            dic[k][1] = max(dic[k][1], b)
        else:
            dic[k] = [b, b]
    if len(dic) == 1:
        return 0
    ks = sorted(dic.keys())
    n = len(ks)
    min_x = min_y = float('inf')
    max_x = max_y = float('-inf')
    for i in range(1, n):
        k1 = ks[i - 1]
        min_b1, max_b1 = dic[k1]
        k2 = ks[i]
        min_b2, max_b2 = dic[k2]
        diff_k = k1 - k2
        min_x = min(min_x, (max_b2 - min_b1) / diff_k)
        max_x = max(max_x, (min_b2 - max_b1) / diff_k)
        min_y = min(min_y, (k1 * max_b2 - k2 * min_b1) / diff_k)
        max_y = max(max_y, (k1 * min_b2 - k2 * max_b1) / diff_k)
    return (max_x - min_x) * (max_y - min_y)

在这里插入图片描述

Guess you like

Origin blog.csdn.net/weixin_48994268/article/details/118763507