[LeetCode] 973. K Closest Points to Origin 最接近原點的K個點

2021-03-02 刷盡天下

We have a list of points on the plane.  Find the K closest points to the origin (0,0).

(Here, the distance between two points on a plane is the Euclidean distance.)

You may return the answer in any order.  The answer is guaranteed to be unique (except for the order that it is in.)

Example 1:

Input: points = [[1,3],[-2,2]], K = 1Output: [[-2,2]]Explanation:The distance between (1, 3) and the origin is sqrt(10).The distance between (-2, 2) and the origin is sqrt(8).Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.We only want the closest K = 1 points from the origin, so the answer is just [[-2,2]].

Example 2:

Input: points = [[3,3],[5,-1],[-2,4]], K = 2Output: [[3,3],[-2,4]](The answer [[-2,4],[3,3]] would also be accepted.)

Note:

1<=K<=points.length<=10000

-10000<points[i][0]<10000

-10000<points[i][1]<10000

這道題給了平面上的一系列的點,讓求最接近原點的K個點。基本上沒有什麼難度,無非就是要知道點與點之間的距離該如何求。一種比較直接的方法就是給這個二維數組排序,自定義排序方法,按照離原點的距離從小到大排序,注意這裡我們並不需要求出具體的距離值,只要知道互相的大小關係即可,所以並不需要開方。排好序之後,返回前k個點即可,參見代碼如下:

解法一:

class Solution {public:    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {        sort(points.begin(), points.end(), [](vector<int>& a, vector<int>& b) {          return a[0] * a[0] + a[1] * a[1] < b[0] * b[0] + b[1] * b[1];        });        return vector<vector<int>>(points.begin(), points.begin() + K);    }};

下面這種解法是使用最大堆 Max Heap 來做的,在 C++ 中就是用優先隊列來做,這裡維護一個大小為k的最大堆,裡面放一個 pair 對兒,由距離原點的距離,和該點在原數組中的下標組成,這樣優先隊列就可以按照到原點的距離排隊了,距離大的就在隊首。這樣每當個數超過k個了之後,就將隊首的元素移除即可,最後把剩下的k個點存入結果 res 中即可,參見代碼如下:

解法二:

class Solution {public:    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {        vector<vector<int>> res;        priority_queue<pair<int, int>> pq;        for (int i = 0; i < points.size(); ++i) {            int t = points[i][0] * points[i][0] + points[i][1] * points[i][1];            pq.push({t, i});            if (pq.size() > K) pq.pop();        }        while (!pq.empty()) {            auto t = pq.top(); pq.pop();            res.push_back(points[t.second]);        }        return res;    }};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/973

類似題目:

Kth Largest Element in an Array

Top K Frequent Elements

Top K Frequent Words

參考資料:

https://leetcode.com/problems/k-closest-points-to-origin/

https://leetcode.com/problems/k-closest-points-to-origin/discuss/217999/JavaC%2B%2BPython-O(N)

https://leetcode.com/problems/k-closest-points-to-origin/discuss/221532/C%2B%2B-STL-quickselect-priority_queue-and-multiset

https://leetcode.com/problems/k-closest-points-to-origin/discuss/220235/Java-Three-solutions-to-this-classical-K-th-problem.

LeetCode All in One 題目講解匯總(持續更新中...)

相關焦點

  • LeetCode-25.K個一組翻轉鍊表(Reverse Nodes in k-Group)
    K個一組翻轉鍊表給你一個鍊表,每 k 個節點一組進行翻轉,請你返回翻轉後的鍊表。k 是一個正整數,它的值小於或等於鍊表的長度。如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。示例:給你這個鍊表:1->2->3->4->5當 k = 2 時,應當返回: 2->1->4->3->5當 k = 3 時,應當返回: 3->2->1->4->5說明:你的算法只能使用常數的額外空間。
  • LeetCode-23.合併K個排序鍊表(Merge k Sorted Lists)
    這是前面Merge Two Sorted Lists的一個follow-up排序超大數量級的數據,可以分成N個機器分別排序
  • leetcode-347前K個高頻元素
    347前K個高頻元素 https://leetcode-cn.com/problems/top-k-frequent-elements/1、題目描述給定一個非空的整數數組,返回其中出現頻率前 k 高的元素。
  • LeetCode 23. Merge k Sorted Lists
    個列表,總長度為$N$,那麼平均每個列表長度為$\frac{N}{k}$,k個列表合併為一個共需要$k-1$合併。空間複雜度: $O(1)$,代碼中未使用遞歸### 法三最簡單的方法就是先將k個列表不管順序的合併為長度為$N$的列表,再用快排等高效的排序方法進行排序即可。
  • ​LeetCode刷題實戰25:K 個一組翻轉鍊表
    今天和大家聊的問題叫做K 個一組翻轉鍊表,我們先來看題面:https://leetcode-cn.com/problems/reverse-nodes-in-k-groupGiven a linked list, reverse the nodes of a linked list k at a time and return its
  • top k frequent words(前K個高頻單詞)
    示例 1:輸入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2輸出: ["i", "love"]解析: "i" 和 "love" 為出現次數最多的兩個單詞,均為2次。    注意,按字母順序 "i" 在 "love" 之前。
  • leetcode-378有序矩陣中第 K 小的元素
    3、二分法,時間複雜度logN,空間複雜度1[最優]378有序矩陣中第 K 小的元素 https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/1、題目描述給你一個 n x n 矩陣 matrix
  • 漫畫:刪去k個數字後的最小值
    讓我們舉幾個慄子:給定整數1593212,刪去3個數字,新整數的最小情況是1212給定整數30200,刪去1個數字,新整數的最小情況是200/** * 刪除整數的k個數字,獲得刪除後的最小值 * @param num  原整數 * @param k  刪除數量 */public static
  • 2020初三數學複習:原點是位似中心,相似比為K,接下來該怎麼辦
    位似變換有一個非常重要的性質,在平面直角坐標系中,如果位似變換是以原點為位似中心,相似比為k,那麼位似圖形對應點的坐標的比等於k或﹣k。那麼,在本章中,歷年來都有哪些容易丟分的中考真題出現呢?分析利用位似圖形的性質,結合兩圖形的位似比進而得出C點坐標.解答解:∵以原點O為位似中心,在第一象限內將線段AB縮小為原來的後得到線段CD,∴端點C的橫坐標和縱坐標都變為A點的橫坐標和縱坐標的一半,又∵A(6,8),∴端點C的坐標為(3,4).故選:C.6.
  • 機器學習十大經典算法之K-Means聚類算法
    K-Means聚類算法步驟K-Means聚類步驟是一個循環迭代的算法,具體·步驟如下:1、先隨機選取K個對象作為初始的聚類中心,隨機選擇K個初始中心點;2、計算每個對象與各個種子聚類中心之間的距離,按照距離初始中心點最小的原則,把每個對象分配給距離它最近的聚類中心。聚類中心以及分配給它們的對象就代表一個聚類。
  • AK leetcode 流浪計劃 - 回文串
    (反證,如果是的話,rad[i]肯定要增加)由於rad[i-k]=5, 說明左邊以a為中心最多可以向2邊擴展5個字符,說明可以以a(下標i-k)為中心擴展 i-k - i-rad[i] = rad[i]-k個字符,對稱到右邊就是以a(下標i+k)為中心擴展 i+rad[i] - (i+k) = rad[i]-k 個字符
  • leetcode-23. Merge k Sorted Lists
    我們用 N表示鍊表的總長度,考慮最壞情況,k 個鍊表的長度相等,都為 n 。解法一 暴力破解簡單粗暴,遍歷所有的鍊表,將數字存到一個數組裡,然後用快速排序,最後再將排序好的數組存到一個鍊表裡。1 個鍊表合併,新生成的再和第 2 個鍊表合併,新生成的再和第 3 個鍊表合併...直到全部合併完。
  • 數據分析入門系列教程-K-Means原理
    我們定義了一個 self_kmeans 的函數,接收兩個參數,第一個是樣本數據,是矩陣的形式;第二個是需要聚類的數量 k接著我們通過 shape 屬性獲取到矩陣數據的行和列的數值,再定義聚類結果 results,用於存儲最終的聚類結果。
  • 【機器學習基礎】數學推導+純Python實現機器學習算法3:k近鄰
    說它獨特,是因為 k 近鄰不像其他模型有損失函數、有優化算法、有訓練過程。對於給定的實例數據和實例數據對應所屬類別,當要對新的實例進行分類時,根據這個實例最近的 k 個實例所屬的類別來決定其屬於哪一類。所以相對於其它機器學習模型和算法,k 近鄰總體上而言是一種非常簡單的方法。
  • python大戰leetcode(一)
    對於算法崗,leetcode的重要性就不用多說了。大廠必考,職業生涯的前一半,或多或少都會和它有點關係。
  • [LeetCode] 943. Find the Shortest Superstring 找到最短的超級字符串
    Example 1:Input: ["alex","loves","leetcode"]Output: "alexlovesleetcode"Explanation: All permutations of "alex","loves","leetcode" would also be accepted.
  • Reverse Nodes in k-Group
    Reverse Nodes in k-GroupGiven a linked list, reverse the nodes of a linked list k at a time and return its modified list.
  • 反比例函數的比例係數k的幾何意義——記住這三個公式
    反比例函數y=k/x(k≠0)的比例係數k的幾何意義(1)、S△AOP=ⅠkⅠ/2分析:如圖①,>(3)、S△APP'=2ⅠkⅠ(P'為P關於原點的對稱點)分析:如圖③設P(x,y)則P'(-x,-y)ⅠAP'Ⅰ=Ⅰx-(-x)Ⅰ=2ⅠxⅠ同理ⅠAPⅠ=2ⅠyⅠ
  • K-Means聚類算法
    簡單來說,之前的算法中我們是利用特徵 x 和類別 y 來進行訓練、分類的,而無監督學習是指不需要我們提供具體的類別 y ,而讓數據自己聚在一起,形成 k 個簇,以實現分類的目的。具體方法是通過對給定的樣本進行劃分,分為 k 個簇,使得簇內的點儘量緊密的連在一起,而簇間的距離儘量大,評判的標準就是通過歐氏距離。