HashMap 数组应用面试题(Point)
今天看了一题面试题,以为很简单,不过自己写了遍,没有完全写出来:
题目是这样的:
给定一些 points 和一个 origin,从 points 中找到 k 个离 origin 最近的点。按照距离由小到大返回。如果两个点有相同距离,则按照x值来排序;若x值也相同,就再按照y值排序。
样例
给出 points = [[4,6],[4,7],[4,4],[2,5],[1,1]], origin = [0, 0], k = 3
返回 [[1,1],[2,5],[4,4]]
首先我们先创建一个Point类
1 package work; 2 3 public class Point { 4 private int x; 5 private int y; 6 7 8 public Point(int x, int y) { 9 super(); 10 this.x = x; 11 this.y = y; 12 } 13 public int getX() { 14 return x; 15 } 16 public void setX(int x) { 17 this.x = x; 18 } 19 public int getY() { 20 return y; 21 } 22 public void setY(int y) { 23 this.y = y; 24 } 25 @Override 26 public String toString() { 27 return " [" + x +","+ y + "]"; 28 } 29 30 public Point getPoint(Point x){ 31 return x; 32 } 33 34 }
再创建一个main方法,用来调用函数和执行程序
1 public class Solution { 2 3 public static void main(String[] args) { 4 Point[] points = new Point[4]; 5 points[0] = new Point(5, 5); 6 7 points[1] = new Point(7, 8); 8 points[2] = new Point(2, 5); 9 points[3] = new Point(4, 7); 10 11 Point point = new Point(4, 4); 12 13 Point[] s = kClosest(points, point, 3); 14 for (Point p : s) { 15 System.out.println(p); 16 } 17 18 } 19 }
根据题目要求,我们可以封装一个求点点之间距离的方法,直接放在main方法下面
1 public static double lengths(Point points, Point origin) { 2 3 return Math.sqrt(Math.pow(Math.abs(points.getX() - origin.getX()), 2) 4 + Math.pow(Math.abs(points.getY() - origin.getY()), 2)); 5 }
最后就是我们的重点了,实现函数并返回一个point数组
1 public static Point[] kClosest(Point[] points, Point origin, int k) { 2 if (k > points.length) { 3 Point p = new Point(0, 0); 4 Point[] arrLength = new Point[1]; 5 arrLength[0] = p; 6 return arrLength; 7 } 8 Point[] arrLength = new Point[points.length]; 9 HashMap<Point, Double> allPoint = new HashMap<Point, Double>(); 10 for (int i = 0; i < points.length; i++) { 11 double length1 = lengths(points[i], origin); 12 allPoint.put(points[i], length1); 13 } 14 Set<Point> set = allPoint.keySet(); 15 16 Iterator<Point> ite = set.iterator(); 17 int count = 0; 18 //循环迭代器 19 while (ite.hasNext()) { 20 //获取map中的key 21 Point ts = ite.next(); 22 23 //下标为0的时候,把key赋值到arrLength数组 24 Point s=null; 25 if (count == 0) { 26 27 arrLength[0] = ts.getPoint(ts); 28 29 } else { 30 //当前下标数组获取值 31 arrLength[count]=ts.getPoint(ts); 32 33 //当计数大于0的时候,进行循环判断 34 for (int n = 0; n < count; n++) { 35 36 //判断当前的L长度与数组里面所有L比较,判断大于L的n 37 38 39 boolean bl=allPoint.get(ts) < allPoint.get(arrLength[n]); 40 41 if (bl) { 42 //获取下标n,将n后面的数组值后移一位 43 44 for (int num = count; num > n; num--) { 45 46 47 arrLength[num] = arrLength[num-1]; 48 49 } 50 arrLength[n]=ts.getPoint(ts); 51 52 break; 53 } 54 55 } 56 } 57 count++; 58 59 } 60 61 62 Point[] arrLength1 = new Point[k]; 63 64 System.arraycopy(arrLength, 0, arrLength1, 0, k); 65 66 return arrLength1; 67 }
功能基本实现,由于个人比较懒惰,所以没有对相同距离x,y坐标的判断。
也是个人能力有限,很久没有接触这种纯面试题了,看来要好好学习,多操练操练。。。。
实现思路:
1.先把Point对象和对应到源点长度,前者作为key,后者作为value存在Hashmap里面,由于不考了会重复点,所以point是唯一的;
2.排序对应的value
2.1 使用迭代器,获取hashmap对应的key,并把key遍历放进新的数组arrLength;首先把第一个放进去
2.2 迭代获取第二个key,并获取value和第一个比较,如果value小于第一个,执行呼唤。
2.3 依次判断,每次循环前,数组都是已经从小到大排序,只需要找到第一个大于当前value的point,并把后面所有的Point在数组中下标后移一位。
3.通过K值,来截取数组,并生成新的数组,并return
浙公网安备 33010602011771号