《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刷题100天—447. 回旋镖的数量( 哈希表)—day37
Leetcode刷题100天—447. 回旋镖的数量( 哈希表)—day37