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:

1

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

示例2:

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ggaoda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值