题目描述:
我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。
(这里,平面上两点之间的距离是欧几里德距离。)
你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。
示例 1:
输入:points = [[1,3],[-2,2]], K = 1
输出:[[-2,2]]
解释:
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。
示例 2:
输入:points = [[3,3],[5,-1],[-2,4]], K = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)
提示:
1 <= K <= points.length <= 10000
-10000 < points[i][0] < 10000
-10000 < points[i][1] < 10000
这道题我想了好长时间,昨晚写道12:00没刚出来,今天调试了一上午,跑出来竟然超时,我天那,要瘦了,超时代码如下:
public int[][] kClosest(int[][] points, int K) {
//把下标记录下来,存储k个
if(K >= points.length){
return points;
}
List<Integer> tem = new ArrayList<>();
for (int i = 0; i < points.length; i++) {
if(tem.size() == 0){
tem.add(0,i);
continue;
}
int lu1 = get(points[i][0], points[i][1]);
if(get(points[tem.get(0)][0],points[tem.get(0)][1]) >= lu1){
tem.add(0,i);
System.out.println("最先的为"+ tem.toString());
}else if (tem.size() == 1) {
if(lu1 <= get(points[tem.get(0)][0], points[tem.get(0)][1])){
tem.add(0,i);
}else {
tem.add(1,i);
}
continue;
} else{
//去掉头尾找中间哪一个不符合
boolean fa = true;
for (int j = 0; j < tem.size() - 1; j++) {
if(get(points[tem.get(j)][0],points[tem.get(j)][1]) <= lu1 && get(points[tem.get(j + 1)][0],points[tem.get(j + 1)][1]) >= lu1){
tem.add(j + 1, i);
fa = false;
System.out.println(tem.toString());
break;
}
}
if(fa){
tem.add(tem.size(),i);
}
}
}
int [][] result = new int[K][2];
System.out.println(tem.toString());
for (int i = 0; i < result.length; i++) {
result[i][0] = points[tem.get(i)][0];
result[i][1] = points[tem.get(i)][1];
}
return result;
}
//写一个函数,从index开始进行,并且之前被覆盖的数字是dig
public int get(int x,int y){
return x * x + y * y;
}
接下来使用Java的TreeMap来进行尝试,首先简单了解一下TreeMap
- TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
- TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
- TreeMap 实现了Cloneable接口,意味着它能被克隆。
- TreeMap 实现了java.io.Serializable接口,意味着它支持序列化。
- TreeMap基于红黑树(Red-Black tree)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
- TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。
另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fastl的。
TreeMap的API
Map.Entry<K,V> ceilingEntry(K key)
返回一个键-值映射关系,它与大于等于给定键的最小键关联;如果不存在这样的键,则返回 null。
K ceilingKey(K key)
返回大于等于给定键的最小键;如果不存在这样的键,则返回 null。
void clear()
从此映射中移除所有映射关系。
Object clone()
返回此 TreeMap 实例的浅表副本。
Comparator<? super K> comparator()
返回对此映射中的键进行排序的比较器;如果此映射使用键的自然顺序,则返回 null。
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value)
如果此映射为指定值映射一个或多个键,则返回 true。
NavigableSet<K> descendingKeySet()
返回此映射中所包含键的逆序 NavigableSet 视图。
NavigableMap<K,V> descendingMap()
返回此映射中所包含映射关系的逆序视图。
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。
Map.Entry<K,V> firstEntry()
返回一个与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。
K firstKey()
返回此映射中当前第一个(最低)键。
Map.Entry<K,V> floorEntry(K key)
返回一个键-值映射关系,它与小于等于给定键的最大键关联;如果不存在这样的键,则返回 null。
K floorKey(K key)
返回小于等于给定键的最大键;如果不存在这样的键,则返回 null。
V get(Object key)
返回指定键所映射的值,如果对于该键而言,此映射不包含任何映射关系,则返回 null。
SortedMap<K,V> headMap(K toKey)
返回此映射的部分视图,其键值严格小于 toKey。
NavigableMap<K,V> headMap(K toKey, boolean inclusive)
返回此映射的部分视图,其键小于(或等于,如果 inclusive 为 true)toKey。
Map.Entry<K,V> higherEntry(K key)
返回一个键-值映射关系,它与严格大于给定键的最小键关联;如果不存在这样的键,则返回 null。
K higherKey(K key)
返回严格大于给定键的最小键;如果不存在这样的键,则返回 null。
Set<K> keySet()
返回此映射包含的键的 Set 视图。
Map.Entry<K,V> lastEntry()
返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。
K lastKey()
返回映射中当前最后一个(最高)键。
Map.Entry<K,V> lowerEntry(K key)
返回一个键-值映射关系,它与严格小于给定键的最大键关联;如果不存在这样的键,则返回 null。
K lowerKey(K key)
返回严格小于给定键的最大键;如果不存在这样的键,则返回 null。
NavigableSet<K> navigableKeySet()
返回此映射中所包含键的 NavigableSet 视图。
Map.Entry<K,V> pollFirstEntry()
移除并返回与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。
Map.Entry<K,V> pollLastEntry()
移除并返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。
V put(K key, V value)
将指定值与此映射中的指定键进行关联。
void putAll(Map<? extends K,? extends V> map)
将指定映射中的所有映射关系复制到此映射中。
V remove(Object key)
如果此 TreeMap 中存在该键的映射关系,则将其删除。
int size()
返回此映射中的键-值映射关系数。
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
返回此映射的部分视图,其键的范围从 fromKey 到 toKey。
SortedMap<K,V> subMap(K fromKey, K toKey)
返回此映射的部分视图,其键值的范围从 fromKey(包括)到 toKey(不包括)。
SortedMap<K,V> tailMap(K fromKey)
返回此映射的部分视图,其键大于等于 fromKey。
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive)
返回此映射的部分视图,其键大于(或等于,如果 inclusive 为 true)fromKey。
Collection<V> values()
返回此映射包含的值的 Collection 视图。
实现代码
class Solution {
public int[][] kClosest(int[][] points, int K) {
//根据题目意思,每个点到原点的欧几里德距离都不同,可以用距离作为key
//Map选择TreeMap是因为TreeMap的key是有序(从小到大)
Map<Double,int[]> map=new TreeMap<>();
for (int i=0;i<points.length;i++){
int x=points[i][0];
int y=points[i][1];
//某个点到原点的欧几里德距离为坐标值的平方之和开根号即可
double distance=Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
map.put(distance,points[i]);
}
int[][] result=new int[K][2];
Iterator<Map.Entry<Double,int[]>> it=map.entrySet().iterator();
//当前遍历到第几个元素,用于控制点的个数
int index=0;
while (it.hasNext()){
int[] point=it.next().getValue();
result[index]=point;
if(index+1==K){
break;
}else{
++index;
}
}
return result;}
}
其实这个代码是有问题的,但是通过了,因为距离如果相等的话,就会覆盖之前的距离,因此这是需要注意,改天上传没有问题的