《LeetCode之每日一题》:148.回旋镖的数量

Posted 是七喜呀!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:148.回旋镖的数量相关的知识,希望对你有一定的参考价值。

回旋镖的数量


题目链接: 回旋镖的数量

有关题目

给定平面上 n 对 互不相同 的点 points ,其中 points[i] = [xi, yi] 。

回旋镖 是由点 (i, j, k) 表示的元组 ,
其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。

返回平面上所有回旋镖的数量。
示例 1:

输入:points = [[0,0],[1,0],[2,0]]
输出:2
解释:两个回旋镖为 [[1,0],[0,0],[2,0]][[1,0],[2,0],[0,0]]
示例 2:

输入:points = [[1,1],[2,2],[3,3]]
输出:2
示例 3:

输入:points = [[1,1]]
输出:0
提示:

n == points.length
1 <= n <= 500
points[i].length == 2
-10^4 <= xi, yi <= 10^4
所有点都 互不相同

题解

Tips

①
	C++ 11原本的auto 写法 for(auto & j : cnt),然后下方使用 j.first,j.second。
	
	C++17的写法改成,可以直接取 map 里面 [v1, v2] 充当 j.first 及 j.second,
	如果下方不需要读值则可以用_代替
②
  auto&auto &&的区别 
	&为引用,相当于C中的指针,拿到所引用数据的地址,
	
	&&为右值引用,右值可以看作程序运行中的临时结果,直接引用返回的对象,避免了对象复制,从而提高效率。

法一:枚举 + 哈希表
参考官方题解

思路:
对于点points[i],有 m 个点到其距离相等,结合排列数的知识
我们需要从中选取两个,故有 A(2,m) = m * (m - 1)中组合

我们使用哈希表键存储距离的平方,值存储 m 个点,
对于每一个点points[i],我们更新一次答案,直至枚举一遍数组
class Solution {
public:
    int numberOfBoomerangs(vector<vector<int>>& points) {
        int ans = 0;
        for (auto& p : points){
            unordered_map<int, int> mp;
            for (auto& p1 : points){
                int squareOfDistance = (p[0] - p1[0]) * (p[0] - p1[0]) +
                    (p[1] - p1[1]) * (p[1] - p1[1]);
                ++mp[squareOfDistance];
            }
            for (auto& [_, m] : mp){
                ans += m * (m - 1);//排列数A(2,m) = m * (m - 1);
            }
        }
        return ans;
    }
};

时间复杂度:O(n^2),n 为points数组的长度
空间复杂度:O(n),哈希表存储所需O(n)复杂度

法二:优化法一
参考官方题解评论区下梦璃夜·天星

空间优化,少一次遍历。

利用排列组合中,每次多一个点,该点和前面每个点各有两个新的组合。
class Solution {
public:
    int numberOfBoomerangs(vector<vector<int>>& points) {
        int ans = 0;
        unordered_map<int, int> mp;
        for (auto&& p1 : points){
            mp.clear();
            for (auto&& p2 : points){
                int dis = (p1[0] - p2[0]) * (p1[0] - p2[0]) + 
                    (p1[1] - p2[1]) * (p1[1] - p2[1]);
                ans += 2 * mp[dis]++;
            }
        }
        return ans;
    }
};

时间复杂度:O(n^2),n 为points数组的长度
空间复杂度:O(n)

以上是关于《LeetCode之每日一题》:148.回旋镖的数量的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 678. 有效的括号字符串(贪心,动规) / 4. 寻找两个正序数组的中位数(二分,关键题) / 447. 回旋镖的数量

leetcode中等447回旋镖的数量

Leetcode刷题100天—447. 回旋镖的数量( 哈希表)—day37

Leetcode刷题100天—447. 回旋镖的数量( 哈希表)—day37

LeetCode 447 回旋镖的数量[Map] HERODING的LeetCode之路

《LeetCode之每日一题》:279.有效的数独