leetcode-149.直线上最多的点数
哈希表
哈希表,又称散列表,使用 O(n) 空间复杂度存储数据,通过哈希函数映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。
C++ 中的哈希集合为 unordered_set,可以查找元素是否在集合中。如果需要同时存储键和值,则需要用 unordered_map,可以用来统计频率,记录内容等等。
如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的
位置,这样空间复杂度就可以降低为常数。
如果需要大小关系的维持,且插入查找并不过于频繁,则可以使用有序的 set/map 来代替unordered_set/unordered_map。
题目详情
给你一个数组 points
,其中 points[i] = [xi, yi]
表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。
示例1:
输入:points = [[1,1],[2,2],[3,3]]
输出:3
示例2:
输入:points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出:4
思路:
对于每个点,我们对其它点建立哈希表,统计同一斜率的点一共有多少个。
另外也要考虑斜率不存在和重复坐标的情况。
注意:在遍历每个点时,对于数组中位置 i 的点,我们只需要考虑 i 之
后的点即可,因为 i 之前的点已经考虑过 i 了。
我的代码:
class Solution
{
public:
int maxPoints(vector<vector<int>>& points)
{
unordered_map<double, int> hash; //<斜率, 点个数>
int max_count = 0, same = 1, same_y = 1;
for (int i = 0; i < points.size(); ++i)
{
same = 1, same_y = 1; //特殊情况 same_y:y坐标相同(斜率不存在) same:重复坐标 都初始化为1(自身)
for (int j = i + 1; j < points.size(); ++j)
{
//嵌套if处理特殊情况
if (points[i][1] == points[j][1]) //如果y坐标相同
{
++same_y;
if (points[i][0] == points[j][0]) //如果x坐标也相同
{
++same;
}
}
else //不属于特殊情况---求斜率
{
double dx = points[i][0] - points[j][0], dy = points[i][1] - points[j][1];
++hash[dx / dy];
}
}
max_count = max(max_count, same_y);// 先用斜率不存在的情况更新max_count
for (auto item: hash) //再用重复坐标+相同斜率来更新max_count
{
max_count = max(max_count, same + item.second);
}
hash.clear(); //clear进行下一轮循环
}
return max_count;
}
};