问题
给定平面上的n个点,问是否存在一条平行于y轴的直线,使得这n个点相对于这条直线对称。
算法分析
因为对称轴一定平行于y轴,这看起来缩小了穷举范围(可是我们真的要穷举可能的对称轴吗?有实无限个可能点对称轴...)
那么我们怎么找到那条对称轴?对称轴的特点就是每一个点都在另一边有一个对应的点。第一想法是:最左边的点一定对应某个最右边的点,因此最左边的点和最右边的点的中点应该在对称轴上。当然还有很多其他的找对称轴的方法,比如求所有x坐标的平均值。
找到了对称轴的位置,我们就可以通过HashMap判断是否每一个点都有对应的点,最后输出答案即可。
时间复杂度为O(N)。
代码
1 public static boolean isReflected(int[][] points){ 2 int min=Integer.MAX_VALUE; 3 int max=Integer.MIN_VALUE; 4 HashMap<Integer, HashSet<Integer>> hashMap = new HashMap<>(); 5 for(int i=0; i<points.length; i++){ 6 min=Math.min(min, points[i][0]); 7 max=Math.max(max, points[i][0]); 8 if(!hashMap.containsKey(points[i][1])){ 9 HashSet<Integer> set = new HashSet<>(); 10 set.add(points[i][0]); 11 hashMap.put(points[i][1], set); 12 } 13 else{ 14 hashMap.get(points[i][1]).add(points[i][0]); 15 } 16 } 17 /* 18 * max-y0=y0-min 19 * p-y0=y0-p' 20 * => p'=max+min-p 21 * */ 22 for(int i=0; i<points.length; i++){ 23 if(!hashMap.containsKey(points[i][1]) 24 || !hashMap.get(points[i][1]).contains(max+min-points[i][0])){ 25 return false; 26 } 27 } 28 return true; 29 }
进价题
是否存在一条直线使得这n个点关于这条直线对称?