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

posted on 2017-08-30 16:29  陈陈之之  阅读(521)  评论(0)    收藏  举报