193、最接近原點的K個點

題目描述:
我們有一個由平面上的點組成的列表 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

  1. TreeMap 是一個有序的key-value集合,它是通過紅黑樹實現的。TreeMap 繼承於AbstractMap,所以它是一個Map,即一個key-value集合。
  2. TreeMap 實現了NavigableMap接口,意味着它支持一系列的導航方法。比如返回有序的key集合。
  3. TreeMap 實現了Cloneable接口,意味着它能被克隆。
  4. TreeMap 實現了java.io.Serializable接口,意味着它支持序列化。
  5. TreeMap基於紅黑樹(Red-Black tree)實現。該映射根據其鍵的自然順序進行排序,或者根據創建映射時提供的 Comparator 進行排序,具體取決於使用的構造方法。
  6. 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;}
}

其實這個代碼是有問題的,但是通過了,因爲距離如果相等的話,就會覆蓋之前的距離,因此這是需要注意,改天上傳沒有問題的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章