【面试经典 150 | 数学】直线上最多的点数

文章目录

  • 写在前面
  • Tag
  • 题目来源
  • 解题思路
    • 方法一:枚举直线+遍历统计
    • 方法二:枚举斜率+哈希统计
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

【数学-点在线上】


题目来源

149. 直线上最多的点数


解题思路

方法一:枚举直线+遍历统计

我们都知道两点确定一条直线,为了统计最多有多少个点可以落在同一条直线上,我们可以枚举所有的直线,然后统计剩余落在该直线上的点的个数,最后取出不同直线上的点数的最大值即为最终答案。

为了判断点 p 是否落在点 xy 确定的直线上,我们通过三点的任意两点之间的斜率是否相同来确定。

比如可以判断点 xy 的斜率与 yp 之间的斜率是否一致,即判断

y [ 1 ] − x [ 1 ] y [ 0 ] − x [ 0 ] = y [ 1 ] − p [ 1 ] y [ 0 ] − p [ 0 ] \frac{y[1] - x[1]}{y[0] - x[0]} = \frac{y[1] - p[1]}{y[0] - p[0]} y[0]x[0]y[1]x[1]=y[0]p[0]y[1]p[1]

是否成立。但是除法运算容易引发精度误差,为了防止这一问题对结果的影响,我们可以将上式转换成乘法表达式,直接判断:

( y [ 1 ] − p [ 1 ] ) ∗ ( y [ 0 ] − x [ 0 ] ) = ( y [ 1 ] − x [ 1 ] ) ∗ ( y [ 0 ] − p [ 0 ] ) (y[1] - p[1]) * (y[0] - x[0]) = (y[1] - x[1]) * (y[0] - p[0]) (y[1]p[1])(y[0]x[0])=(y[1]x[1])(y[0]p[0])

是否成立。

实现代码

class Solution {
public:int maxPoints(vector<vector<int>>& points) {int res = 0, n = points.size();if (n == 1) return 1;for (int i = 0; i < n-1; ++i) {             // x 点for (int j = i + 1; j < n; ++j) {       // y 点int cnt = 0;    for (int k = 0; k < n; ++k) {       // p 点if ((points[j][1] - points[k][1]) * (points[j][0] - points[i][0]) == (points[j][1] - points[i][1]) * (points[j][0] - points[k][0])) {++cnt;}}res = max(res, cnt);}}return res;}
};

复杂度分析

时间复杂度: O ( n 3 ) O(n^3) O(n3)

空间复杂度: O ( 1 ) O(1) O(1)

方法二:枚举斜率+哈希统计

方法二参考 枚举直线 + 哈希表统计。

在方法一中枚举的是直线,其实本质上枚举的是斜率,接着判断其它点与该直线的一点连接的直线斜率是否一致。

现在,我们可以直接枚举所有出现的 直线斜率,使用哈希表统计所有斜率对应的点的数量,在所有值中去个最大值即为答案。

注意:在使用哈希表进行保存时,为了避免精度问题,我们直接使用字符串进行保存。同时需要将 斜率 约分干净再记录到哈希表中。

实现代码

class Solution {
public:int maxPoints(vector<vector<int>>& points) {int n = points.size(), res = 1;for (int i = 0; i < n; i++) {map<string, int> map;int maxv = 0;for (int j = i + 1; j < n; j++) {int x1 = points[i][0], y1 = points[i][1], x2 = points[j][0], y2 = points[j][1];int a = x1 - x2, b = y1 - y2;int k = gcd(a, b);string key = to_string(a / k) + "_" + to_string(b / k);map[key]++;maxv = max(maxv, map[key]);}res = max(res, maxv + 1);}return res;}int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
};

复杂度分析

时间复杂度: O ( n 2 × l o g m ) O(n^2 \times logm) O(n2×logm) m m m 为横纵坐标的最大差值,单次最大公约数计算时间复杂度为 O ( l o g m ) O(logm) O(logm)

空间复杂度: O ( n ) O(n) O(n)


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/817178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

改进的注意力机制的yolov8和UCMCTrackerDeepSort的多目标跟踪系统

基于yolov8和UCMCTracker/DeepSort的注意力机制多目标跟踪系统 本项目是一个强大的多目标跟踪系统&#xff0c;基于[yolov8]链接和[UCMCTracker/DeepSot]/链接构建。 &#x1f3af; 功能 多目标跟踪&#xff1a;可以实现对视频中的多目标进行跟踪。目标检测&#xff1a;可以实…

在 VS Code 中使用 GitHub Copilot

Code 结合使用。 GitHub Copilot 是什么 GitHub Copilot 是一个可以帮助你更简单、更快速地编写代码的工具&#xff0c;由 GPT-3 提供支持。你只需编写所需代码的描述——例如&#xff0c;编写一个函数来生成一个随机数&#xff0c;或对一个数组进行排序——Copilot 就会为你…

【Docker】docker原理及使用-1

Docker目录 1️⃣概念2️⃣使用容器的好处2️⃣docker和普通软件启动方式的区别2️⃣docker和传统虚拟机的区别 1️⃣下载安装2️⃣安装步骤 1️⃣必须要掌握的核心概念1️⃣命令2️⃣例子2️⃣练习题目2️⃣进入一下python环境(简洁) 1️⃣解释一下 redis1️⃣docker底层隔离机…

L3 【哈工大_操作系统】操作系统启动

本节要点&#xff1a; 1、理解 OS 启动过程发生了什么&#xff0c;理解 OS 与 硬件 与 应用 之间的关系 2、本节讲解了 setup 模块 和 system 模块实现的功能 1、计算机上电时&#xff0c;操作系统在硬盘&#xff08;磁盘&#xff09;上&#xff0c;为了“取指执行”&#xff0…

康姿百德床垫抗干扰设计,保证你和伴侣睡眠不受影响

康姿百德官网价格公开透明&#xff0c;床垫价格合理质量安全可靠 在我们的一生中&#xff0c;睡眠的时间占据我们生活的大部分。在繁忙的一天结束时&#xff0c;没有什么比沉浸在舒适床垫的温柔拥抱中更让人期待的&#xff0c;让您在睡眠过程中释放一整天的疲惫。康姿百德床垫…

第十五届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组

试题 C: 好数 时间限制 : 1.0s 内存限制: 256.0MB 本题总分&#xff1a;10 分 【问题描述】 一个整数如果按从低位到高位的顺序&#xff0c;奇数位&#xff08;个位、百位、万位 &#xff09;上 的数字是奇数&#xff0c;偶数位&#xff08;十位、千位、十万位 &…

基于Spring Boot的入职匹配推荐系统设计与实现

基于Spring Boot的入职匹配推荐系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 管理员登录界面&#xff0c;登录成功后进入到系统操…

面试经典150题——二叉树的最大深度

1. 题目描述 ​ 2. 题目分析与解析 这个题目有过一定基础的都应该知道&#xff0c;采用递归解决问题&#xff0c;因为要求一个二叉树的深度&#xff08;也就是高度&#xff09;&#xff0c;其实上就是根节点的左子树和右子树中高度最高的那个。因此这个问题就可以拆解为&…

Python爬虫-京东商品评论数据

前言 本文是该专栏的第68篇,后面会持续分享python爬虫干货知识,记得关注。 在本专栏之前,笔者有详细介绍京东滑块验证码的解决方法,感兴趣的同学,可以直接翻阅文章《Python如何解决“京东滑块验证码”(5)》进行查看。 而本文,笔者以京东商品详情页的评论数据为例,通过…

悠络客亮相第十届智慧商业数字化运营高峰论坛

2024年4月12日&#xff0c;由中国零售&#xff08;餐饮&#xff09;CIO俱乐部、《智慧零售与餐饮》新媒体主办的“2024第十届智慧商业数字化运营高峰论坛暨中国零售CIO俱乐部春季思享会”在北京举办。 来自全国各地的商超、便利、生鲜、百货、购物中心、快消品、食品/酒水/鞋服…

探索分布式技术--------------注册中心zookeeper

目录 一、ZooKeeper是什么 二、ZooKeeper的工作机制 三、ZooKeeper特点 四、ZooKeeper数据结构 五、ZooKeeper应用场景 5.1统一命名服务 5.2统一配置管理 5.3统一集群管理 5.4服务器动态上下线 5.5软负载均衡 六、ZooKeeper的选举机制 6.1第一次启动选举机制 6.2非…

国债逆回购交易攻略!

购买国债逆回购的步骤可以按照以下流程进行&#xff1a; 1. 开通证券账户&#xff1a; 首先&#xff0c;您需要拥有一个证券账户&#xff08;也称股票账户&#xff09;。可以通过选择一家信誉良好、服务优质的证券公司进行线上开户。联系券商服务经理&#xff0c;沟通了解不同公…

烧结钕铁硼永磁体是如何生产的?

烧结钕铁硼永磁体是采用粉末冶金法生产的&#xff0c;从备料到成品发货一般要经过十几个工艺环节&#xff0c;在不同阶段还包括若干次检测分析。 整个生产过程是一个系统工程&#xff0c;环环相扣。一般我们将生产磁体毛坯的过程称为前道生产环节&#xff0c;将毛坯加工成最终…

分布式事务 - 个人笔记 @by_TWJ

目录 1. 传统事务1.1. 事务特征1.2. 事务隔离级别1.2.1. 表格展示1.2.2. oracle和mysql可支持的事务隔离级别 2. 分布式事务2.1. CAP指标2.2. BASE理论2.3. 7种常见的分布式事务方案2.3.1. 2PC2.3.2. 3PC2.3.3. TCC2.3.3.1. TCC的注意事项&#xff1a;2.3.3.2. TCC方案的优缺点…

计算机网络 Cisco虚拟局域网划分

一、实验内容 1、分别把交换机命名为SWA、SWB 2、划分虚拟局域网 valn &#xff0c;并将端口静态划分到 vlan 中 划分vlan 方法一&#xff1a;在全局模式下划分vlan&#xff0c;在SWA交换机上创建三个vlan&#xff0c;分别为vlan2&#xff0c;vlan3&#xff0c;vlan4。 方…

OpenCV的查找命中或未命中

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇:OpenCV4.9更多形态转换 下一篇:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 目标 在本教程中&#xff0c;您将学习如何使用 Hit-or-Miss 转换&#xff08;也称为 Hit-and-Miss 转…

树莓派驱动开发--驱动文件代码的浅度分析(以iic的为例)

前言:我使用的代码是正点原子的驱动代码,我们借鉴学习,看多了别人优秀的代码是我们自主完成代码编写的前提! 一. 总体层面梳理 总线-驱动-设备 模型 --把不同功能的外设归类,然后实现统一接口,无法归类的使用虚拟总线来形容,从而实现总线-驱动-设备模型. --为什么要这样?比…

C/C++基础----指针

指针的定义 在c/c中&#xff0c;有一个特殊的变量指向我们电脑中某个内存地址&#xff0c;进而可以让我们操作这段内存&#xff0c;指的就是指针类型 语法&#xff1a; int a 10; int* p &a;&符号是取出某个变量的内存地址 把这个内存地址赋值给一个变量p&#xff…

Java代码基础算法练习-拆分一个三位数的个位、十位、百位-2024.04.14

任务描述&#xff1a;输入一个三位数&#xff0c;逆序输出这个三位数的个位、十位、百位对应的数字&#xff0c;用空格分开。 任务要求&#xff1a; 代码示例&#xff1a; package April_2024;import java.util.Scanner; public class a240414 {public static void main(Strin…

972: 统计利用先序遍历创建的二叉树的宽度

解法&#xff1a; #include<iostream> #include<queue> using namespace std; // 定义二叉树结点 struct TreeNode {char val;TreeNode* left;TreeNode* right;TreeNode(char x) :val(x), left(NULL), right(NULL) {}; }; // 先序递归遍历建立二叉树 TreeNode* bu…