leetcode每日一题-检测正方形
Posted C+++++++++++++++++++
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode每日一题-检测正方形相关的知识,希望对你有一定的参考价值。
文章目录
题目
题目解析
注意此题为计算几何类型的题目,我认为这类问题最重要的就是把这个几何图形用好用的方法去表示出来。
三个重点:
-
点的表示:我们通过上下两点确定正方形的原则来表示,且点的存储方式一点不能用pair,这样效率及其低下,且难以有一定的自由度取操作 x,y 轴,我们采用哈希表套哈希表的方式取存储!
-
点的记录:通过嵌套哈希表完成点的次数记录,比如:
unordered_map<int, unordered_map<int, int>> cnt; cnt[y][x]++;
-
点的枚举:通过嵌套哈希表,可以很好的把 x,y 坐标的对应点数给限制住,所以我们要根据这点可以利用count方法直接把不是同一个纵轴的点给排除,比如:
res += (colCnt.count(x) ? colCnt[x] : 0) * (yCnt.count(x + d) ? yCnt[x + d] : 0) * (colCnt.count(x + d)? colCnt[x + d] : 0); //一旦以上的count方法返回0,即表示该点不是同一个纵轴上的点,则得出结果0,整个res就相当于没有加任何数字。
再比如通过yCnt提前取出在同一个横轴的点:
unordered_map<int, int> & yCnt = cnt[y]; //取和point在同一行的所有点 //这样后续的枚举过程直接可以套用yCnt[x+d]或者yCnt[x-d]来得到对应左右两种情况正方形的点个数。
最后一个优化:由于我们每次枚举同一纵轴上的点不确定是上面还是下面,实际上根本不重要,由于在计算时,我们都会把左右两种正方形的情况给计算完,而这个过程正好是两个相反的
+-
过程,所以无论枚举得到的正方形边长为正还是为负数,都不影响!
解题代码
非常详细的注释了
class DetectSquares
public:
unordered_map<int, unordered_map<int, int>> cnt;
DetectSquares()
void add(vector<int> point)
int x = point[0], y = point[1];
cnt[y][x]++;
int count(vector<int> point)
int res = 0;
int x = point[0], y = point[1];
if (!cnt.count(y))
return 0;
unordered_map<int, int> & yCnt = cnt[y]; //取和point在同一行的所有点
for (auto & [col, colCnt] : cnt)
if (col != y) //由于我们构造正方形是根据上下两条边,故此处枚举的另外一点不能在同一行
// 根据对称性,这里可以不用取绝对值,具体而言就是所有情况根据+-已经包括
int d = col - y;//得到正方形边长,根据这个值可以直接取到对应的另外几个点(如果存在的话)
//这里的colCnt.count(x)用于判断是否和当前点在同一个纵轴,这样才可能构造上下两边,故下面只要有1个为0,则加的都是0
//由于我们指定了必须是同一个纵轴上的点,所以不可能构造出两个相同的正方形!
res += (colCnt.count(x) ? colCnt[x] : 0) * (yCnt.count(x + d) ? yCnt[x + d] : 0) *
(colCnt.count(x + d)? colCnt[x + d] : 0);
res += (colCnt.count(x) ? colCnt[x] : 0) * (yCnt.count(x - d) ? yCnt[x - d] : 0) *
(colCnt.count(x - d) ? colCnt[x - d] : 0);
return res;
;
总结
学到以下:
- 如何通过嵌套哈希表表示点,以及用它表示的而不用pair表示的好处。
- 重点好像也就上面那条。
以上是关于leetcode每日一题-检测正方形的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 2045. 到达目的地的第二短时间(记录第二短时间的bfs) / 1688. 比赛中的配对次数 / 2013. 检测正方形