(阿里巴巴笔试题)直线上安装水塔,水塔到直线上其它点的距离之和最小

直线上有N棵树木,需要在直线上修水塔,使水塔到所有树木的距离最短,时间复杂度为O(N)。(水塔的安装位置在整数处,安装水塔的位置不能有树木)

输入:第一行 树的数目N。第二行N棵数目的坐标值

2<=N<=10^5,

树木的坐标0<=ai<=2^31

输入:

4

0 1 4 6

输出:

9

解释:在第三个位置上修水塔,距离为3+2+1+3=9

if __name__ == "__main__":

    N = int(input())
    data = list(map(int,input().split()))
    data = sorted(data)
    # N = 4
    # data = [0, 1, 4, 6]
    dis = [0 for i in range(min(data), max(data) + 1)]
    dis[0] = 0
    for ele in data:
        dis[0] += abs(min(data) - ele)
    left = 1
    right = N - 1
    for idx, i in enumerate(range(min(data) + 1, max(data) + 1)):
        # 向右移动一个点,右边所有点的距离减去1,左边所有点的距离加1
        if i in data:
            dis[idx + 1] = dis[idx] + left - right
            left += 1
            right -= 1
        else:
            dis[idx + 1] = dis[idx] + left - right
    # # 最后因为有树木的地方不能修水塔,需要删除
    # # dis的索引为0,max[data]-min(data)
    # # 对应着坐标为min(data)到max[data]位置安装水塔计算距离的最小值
    # idx = list(map(minus,data))
    # cur_idx = 0
    # flag = False
    # for i in range(len(dis)):
    #     if i not in idx:
    #         flag = True
    #         if flag:
    #             dis[cur_idx] = dis[i]
    #             cur_idx += 1
    # print(min(dis))

    # 不删除,自己计算最小值,和对应的索引
    min_v=dis[0]
    min_idx=0
    print(dis)
    for idx,ele in enumerate(dis):
        if ele <min_v and idx+min(data) not in data:
            min_v=ele
            min_idx=idx
    
   print(min_v)
   #print(str(min_idx+min(data)),str(min_v)) pass
原文地址:https://www.cnblogs.com/sunupo/p/13472311.html