zoukankan      html  css  js  c++  java
  • 149. Max Points on a Line

    问题描述:

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

    Example 1:

    Input: [[1,1],[2,2],[3,3]]
    Output: 3
    Explanation:
    ^
    |
    |        o
    |     o
    |  o  
    +------------->
    0  1  2  3  4
    

    Example 2:

    Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
    Output: 4
    Explanation:
    ^
    |
    |  o
    |     o        o
    |        o
    |  o        o
    +------------------->
    0  1  2  3  4  5  6
    

    解题思路:

    这道题让我们找在一条直线上的点的最多的数目。

    很容易我们想到把点和其所在的直线构成一个键值对放到map中。

    问题是,如何表示直线?

    若用y = kx + b来表示, x = c则无法表示。

    一开始我用Ax + By + C =0来表示直线,自己构造了一个struct来存放参数,并且自己写了struct的hash方法,来存入unordered_map中。(见C++11 unordered_set & unordered_map 存储结构体(struct)

    我通过 A = y1 - y2 B = x2- y1 C = x1y2 - x2y1来计算,但是这样会出现一个问题,就是由于点的相对距离不同, 明明在一条直线上却会被认为不在一条直线上。

    参考了discussion中的16ms/28ms C++ Solutions with Explanations的答案

    这里用一个pair来存储dx,dy的值,为了避免上述情况的发生,对dx 和 dy求了最大公约数并进行约分。

    同时注意的是,为了避免重复计算多个点,在外部循环时创建map,一次循环结束时找到最大值存储起来。

    还需要注意的是:若两点重合,虽然不能构成线,但是可以认为落在同一条直线上。

    关于如何找到最大公约数:求最大公约数的算法

    代码:

    /**
     * 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<Point>& points) {
            int ret = 0;
            for(int i = 0; i < points.size(); i++){
                map<pair<int,int>, int> m;
                int duplicate = 1;
                for(int j = i+1; j < points.size(); j++){
                    if(points[i].x == points[j].x && points[i].y == points[j].y){
                        duplicate++;
                        continue;
                    }
                    int dx = points[i].x - points[j].x;
                    int dy = points[i].y - points[j].y;
                    int div = gcd(dx, dy);
                    m[{dx/div, dy/div}]++;
                }
                ret = max(duplicate, ret);
                for(auto p:m){
                    ret = max(ret, (p.second+duplicate));
                }
            }
            
            return ret;
        }
    private:
        int gcd(int a, int b){
            while(b){
                int temp = b;
                b = a % b;
                a = temp;
            }
            return a;
        }
    };
  • 相关阅读:
    Java提高篇——通过分析 JDK 源代码研究 Hash 存储机制
    Java提高篇——equals()与hashCode()方法详解
    Java提高篇——equals()方法和“==”运算符
    Java提高篇—— 简单介绍Java 的内存泄漏
    Java提高篇——理解String 及 String.intern() 在实际中的应用
    hbuilder
    angular
    微信小程序
    angular
    angular
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9219366.html
Copyright © 2011-2022 走看看