LeetCode#447 Number of Boomerangs

問題描述

Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters).

Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive).

Example:

Input:
[[0,0],[1,0],[2,0]]

Output:2

Explanation:
The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]]

補充說明:

這個題目的要求大概是這個樣子的:給定一個包含點坐標的list,最大長度為500,找到這個list中所有符合Boomerangs(回旋鏢)規則的點的集合。這個單詞我也沒理解明白,但是根據提供的例子大概可以明白,意思就是生成的這個集合包含三個點i、j、k,點i到點j的距離等于點i到點k的距離。結果輸出為給定這個列表中,滿足這個條件的點集合的個數。

方案分析

  1. 看到這個題目,筆者第一反應就是想到了兩點間的距離公式pow(y2-y1, 2) + pow(x2-x1, 2),畢竟初中數學。
  2. 知道如何判定了,就該想如何選點了,這里有個問題就是要選擇三個點,自然而然想到了循環遍歷,出于小聰明,筆者用python的情況下想到了itertools中的一個函數permutations,這個函數能從一個可迭代的類型對象中選擇指定個數元素,生成tuple集合。是不是很機智??墒沁@是噩夢的開始,先上代碼。

python實現

class Solution(object):
    def numberOfBoomerangs(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        nums = 0
        import itertools
        for point_tuple in itertools.permutations(points, 3):
            print point_tuple
            if pow((point_tuple[1][1] - point_tuple[0][1]),2)\
            + pow((point_tuple[1][0] - point_tuple[0][0]),2)\
            == pow((point_tuple[2][1] - point_tuple[0][1]),2)\
            + pow((point_tuple[2][0] - point_tuple[0][0]),2):
                nums += 1
        return nums

方案分析2

1.上面那個無外乎是在遍歷所有情況,引用了高級函數一樣不會避免枚舉時間過長的問題,所以,上面方法不可行,原理上能講明白,實際時間復雜度太高。

  1. ok,換個思路,使用hashmap,把里面所有的兩點之間的距離計算一下,放到hashmap中,然后根據滿足這個距離里面的點進行組合。這樣就滿足要求了。
  2. 講解一下最后的那個res += pDict[p] * (pDict[p] - 1),這句話的意思是就是,當你發現兩個點的距離為L時候,凡是滿足L距離的點都存在了這個L為key的dict中,此時,你只需要從中任取3點,就能構成這個條件,因此,這樣的組合有p×(p-1)對。

python實現2

class Solution(object):
    def numberOfBoomerangs(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        if len(points) < 3:
            return 0
        res = 0
        for i in range(len(points)):
            pDict = {}
            for j in range(len(points)):
                if j == i:
                    continue
                dis = pow(points[i][0] - points[j][0], 2) + pow(points[i][1] - points[j][1], 2)
                key = str(dis)
                if key in pDict:
                    pDict[key] += 1
                else:
                    pDict[key] = 1
            for p in pDict:
                if pDict[p] > 1:
                    res += pDict[p] * (pDict[p] - 1)
        return res
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,769評論 0 33
  • 題目 Given n points in the plane that are all pairwise dist...
    Eazow閱讀 191評論 0 0
  • 動態規劃(Dynamic Programming) 本文包括: 動態規劃定義 狀態轉移方程 動態規劃算法步驟 最長...
    廖少少閱讀 3,327評論 0 18
  • 讀一讀 總會讀到一篇美文 聽一聽 總會聽到一首好歌 等一等總會等到相愛的人 笑一笑 總會看到生活的美好 幸福就在執...
    南方瀟瀟閱讀 122評論 0 0
  • 每次談到青春這個詞,總有道不盡的話題。每個人的青春中都寫滿了各式各樣的故事,畢業的別離,羞澀而單純的愛情,在球場上...
    迷途囧爺閱讀 2,747評論 0 2