Max Points on a Line | leetcode

Given  n  points on a 2D plane, find the maximum number of points that lie on the same straight line.

以每个点为中心,然后遍历剩余点,找到所有的斜率,如果斜率相同,那么一定共线,每次更新最大点数,最后就是结果。排序O(nlog(n))再乘以n个点,总复杂度O(n2logn)

#include 
   
   
    
    
using namespace std;
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         // Definition for a point. struct Point { int x; int y; Point() : x(0), y(0) {} Point(int a, int b) : x(a), y(b) {} }; class Solution { static bool PointXCompare(const Point &lhs, const Point &rhs) { return lhs.x < rhs.x; } static bool PointYCompare(const Point &lhs, const Point &rhs) { return lhs.y < rhs.y; } static bool FloatCompare(float a, float b) { const float epsilon = 0.000001; return (a - b) < epsilon && (b - a) > -epsilon; } public: int maxPoints(vector 
        
          &points) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. // bug 1: 没有考虑重复点 if (points.size() <= 2) { return points.size(); } int max_count = 2; const float float_max = 3.402823466e+38F ; // 以每个点作为中心,计算其他值到它的slope,并排序,这样如果一样的斜率存在那么一定共线 for (int i = 0; i < points.size() - 1; i++) { // 优化1 当剩余点小于max_point时,退出 if (points.size() - i < max_count) { break; } // 有重复点。。 int repeat_point = 0; vector 
         
           slopes(points.size() - i - 1); //只处理剩余点即可,前面的都已经处理过了 int index = 0; //开始计算斜率并排序 for (int j = i + 1; j < points.size(); j++) { if (points[j].x == points[i].x && points[j].y == points[i].y) { repeat_point++; continue; } if (j != i) { if (points[j].x == points[i].x) { //竖直 slopes[index++] = float_max; } else { slopes[index++] = (float)(points[j].y - points[i].y) / (points[j].x - points[i].x); } } } sort(slopes.begin(), slopes.begin() + index); //找到共线的个数 int cur = 0; float first = slopes[0]; int count = 1; while (++cur < index) { if (FloatCompare(slopes[cur], first)) { count++; } else { count = 1; first = slopes[cur]; } max_count = max(max_count, count + 1 + repeat_point); //数量等于斜率的个数加1个数 } //最后需要更新,因为有一部分点没有考虑 if (index == 0) { max_count = max(max_count, 1 + repeat_point); //没有线段,数量等于自己加上重复点数 } else { max_count = max(max_count, count + 1 + repeat_point); //数量等于斜率的个数加重复点个数 } } return max_count; } }; int main() { Solution so; Point p0(1, 1), p1(2, 1), p2(1, 1), p3(2, 1), p4(3, 3), p5(3, 3); //重点考虑 (0, 0), (1, 0), (0, 0); // (1, 1), (1, 1), (1, 1); vector 
          
            points; points.push_back(p0); points.push_back(p1); points.push_back(p2); // points.push_back(p3); // points.push_back(p4); // points.push_back(p5); cout << so.maxPoints(points) << endl; return 0; } 
           
          
         
       
      
      
     
     
    
    
   
   


以每个点为中心,遍历其他点,找到所有的斜率,但是这是将斜率放到hash表中,O(n2)的复杂度
/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
    int maxPoints(vector
    
    
     
      &points) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        //O(n2)
        if ( points.size() <= 2) {
            return points.size();
        }
        const float float_max = std::numeric_limits
     
     
      
      ::infinity();
        int max_count = 2;
        //以每个点为中心,计算其他值到它的slope,然后使用hash计数即可
        for ( int i = 0; i < points.size() - 1; i++) {
            // 优化1 当剩余点小于max_point时,退出
            if ( points.size() - i < max_count) {
                break;
            }
            // 有重复点。。
            int repeat_point = 0;
            unordered_map
      
      
       
        line_nums;
            float slope;
            for ( int j = i + 1; j < points.size(); j++) {
                if ( points[j].x == points[i].x && points[j].y == points[i].y) {
                    repeat_point++;
                    continue;
                }
                if ( points[j].x == points[i].x) { //竖直
                    slope = float_max;
                }
                else {
                    slope = ( float)( points[j].y - points[i].y) / (points[j].x - points [i].x);
                }
                line_nums[slope]++;
            }
            int max_slope_num = 0;
            for (unordered_map
       
       
        
        ::iterator iter = line_nums.begin(); iter != line_nums.end(); ++iter) {
                max_slope_num = max(max_slope_num, iter->second);
            }
            max_count = max(max_count, repeat_point + max_slope_num + 1);
        }
        return max_count;
    }
};

       
       
      
      
     
     
    
    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值