104. 货仓选址
在一条数轴上有 N N N 家商店,它们的坐标分别为 A 1 A_1 A1~ A N A_N AN。
现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。
为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。
输入格式
第一行输入整数
N
N
N 。
第二行 N N N 个整数 A 1 A_1 A1~ A N A_N AN。
输出格式
输出一个整数,表示距离之和的最小值。
数据范围
1
≤
N
≤
100000
1≤N≤100000
1≤N≤100000,
0
≤
A
i
≤
40000
0≤A_i≤40000
0≤Ai≤40000
输入样例:
4
6 2 9 1
输出样例:
12
算法分析
1、把A[0]~A[N-1]
排序,设货仓在X
坐标处,X
左侧的商店有P
家,右侧的商店有Q
家。若P
< Q
,则每把仓库的选址向右移动1单位距离,距离之和就会变少Q - P
.同理,若P > Q
,则仓库的选址向左移动会使距离之和变小。当P=Q
时为最优解。
2、因此仓库应该建在中位数处,把A进行排序,
当N为奇数时,货仓建在A[(N - 1)/2]
处,
当N为偶数时,仓库建在A[(N - 1)/2 + 1]
处。
如下图举例:
时间复杂度 ( O ( n l o g ( n ) ) (O(nlog(n)) (O(nlog(n))即排序的时间复杂度
import java.util.Scanner;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] arr = new int[n];
for(int i = 0;i < n;i++){
arr[i] = scanner.nextInt();
}
//为了找到正确的中位数,故先排序
Arrays.sort(arr);
//n是奇数时,中位数即(n-1)/2,n时偶数时,货仓可以选在中间两个数之间,包括中间两个数的位置
//为了统一方便,我们选在中间两个数的第一个数,也即(n-1)/2的位置
int mid = (n - 1) / 2;
int res = 0;
for(int i = 0;i < n;i++){//计算每个点到货仓的距离之和
res += Math.abs(arr[i] - arr[mid]);
}
System.out.println(res);
}
}