【滑动窗口】C++算法:可见点的最大数目

作者推荐

动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本

本题涉及知识点

滑动窗口

LeetCode 1610可见点的最大数目

给你一个点数组 points 和一个表示角度的整数 angle ,你的位置是 location ,其中 location = [posx, posy] 且 points[i] = [xi, yi] 都表示 X-Y 平面上的整数坐标。
最开始,你面向东方进行观测。你 不能 进行移动改变位置,但可以通过 自转 调整观测角度。换句话说,posx 和 posy 不能改变。你的视野范围的角度用 angle 表示, 这决定了你观测任意方向时可以多宽。设 d 为你逆时针自转旋转的度数,那么你的视野就是角度范围 [d - angle/2, d + angle/2] 所指示的那片区域。
对于每个点,如果由该点、你的位置以及从你的位置直接向东的方向形成的角度 位于你的视野中 ,那么你就可以看到它。
同一个坐标上可以有多个点。你所在的位置也可能存在一些点,但不管你的怎么旋转,总是可以看到这些点。同时,点不会阻碍你看到其他点。
返回你能看到的点的最大数目。
示例 1:
输入:points = [[2,1],[2,2],[3,3]], angle = 90, location = [1,1]
输出:3
解释:阴影区域代表你的视野。在你的视野中,所有的点都清晰可见,尽管 [2,2] 和 [3,3]在同一条直线上,你仍然可以看到 [3,3] 。
示例 2:
输入:points = [[2,1],[2,2],[3,4],[1,1]], angle = 90, location = [1,1]
输出:4
解释:在你的视野中,所有的点都清晰可见,包括你所在位置的那个点。
示例 3:
输入:points = [[1,0],[2,1]], angle = 13, location = [1,1]
输出:1
解释:如图所示,你只能看到两点之一。
提示:
1 <= points.length <= 105
points[i].length == 2
location.length == 2
0 <= angle < 360
0 <= posx, posy, xi, yi <= 100

滑动窗口

时间复杂度😮(nlogn),瓶颈在排序。
vSee记录了除重合点外,所有点的弧度。注意:angle是角度,要转化成弧度dAngle。
[d - angle/2, d + angle/2] 令d1=d-angle/2,则视野范围为[d1,d1+dAngle/2],d1+dAngle/2可能超过2PI,那样需要查询两次。可以将[2PI,2PI+dAngle]也加到vSee中。这样值需要查询一次。
枚举d1,取值范围为[0,2PI)。
站着的位置点,任何角度都可以看到。

代码

核心代码

class Solution {
public:
	int visiblePoints(vector<vector<int>>& points, int angle, vector<int>& location) {
		vector<double> vSee;
		const double PI = 3.1415926;
		const double dAngel = angle / 180.0 * PI;
		int iLocPointCount = 0;//和人重合的点,任何角度都可以看到
		for (const auto& v : points)
		{
			if ((v[1] == location[1]) && (v[0] == location[0]))
			{
				iLocPointCount++;
				continue;
			}
			double dAng = atan2(v[1] - location[1], v[0] - location[0]);
			vSee.emplace_back(dAng);
		}
		sort(vSee.begin(), vSee.end());
		
		for (int i = 0; (i < vSee.size()) && (vSee[i] <= dAngel); i++)
		{
			vSee.emplace_back(vSee[i] + PI * 2);
		}
		int iRet = 0;
		for (int i = 0,right=0; (i < vSee.size()) && (vSee[i] < PI*2); i++)
		{
			while ((right < vSee.size()) && (vSee[right] <= vSee[i] + dAngel))
			{
				right++;
			}
			iRet = max(iRet, right - i);
		}
		return iRet+ iLocPointCount;
	}
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}
}


int main()
{
	vector<vector<int>> points;
	int angle;
	vector<int> location;
	{
		Solution sln;
		points = { {1,2},{1,3},{1,0} }, angle = 13, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(2, res);
	}
	{
		Solution sln;
		points = { {1,2},{1,-1},{1,0} }, angle = 13, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(2, res);
	}
	{
		Solution sln;
		points = { {1,2},{1,3},{1,0} }, angle = 13, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(2, res);
	}
	{
		Solution sln;
		points = { {3,1},{2,1},{0,1} }, angle = 13, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(2, res);
	}
	{
		Solution sln;
		points = { {2,1},{-1,1},{0,1} }, angle = 13, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(2, res);
	}

	{
		Solution sln;
		points = { {2,1},{2,2},{3,3} }, angle = 90, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(3, res);
	}
	{
		Solution sln;
		points = { {2,1},{2,2},{3,4},{1,1} }, angle = 90, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(4, res);
	}
	{
		Solution sln;
		points = { {1,0},{2,1} }, angle = 13, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(1, res);
	}
	{
		Solution sln;
		points ={ {1,1},{2,2},{3,3},{4,4},{1,2},{2,1} }, angle = 0, location = { 1,1 };
		auto res = sln.visiblePoints(points, angle, location);
		Assert(4, res);
	}
}

2023年4月

class Solution {
public:
int visiblePoints(vector<vector>& points, int angle, vector& location) {
const double PI = 3.1415926;
int iSelfPoints = 0;
std::vector dAngles;
for (const auto& v : points)
{
if ((v[0] == location[0]) && (v[1] == location[1]))
{
iSelfPoints++;
continue;
}
dAngles.emplace_back(atan2(v[1] - location[1], v[0] - location[0]));
}
std::sort(dAngles.begin(), dAngles.end());
int iPointSize = dAngles.size();
for (int i = 0; i < iPointSize; i++)
{
dAngles.emplace_back(dAngles[i] + PI * 2);
}
int iRet = 0;
double dRange = angle / 180.0 * PI;
for (int i = 0; i < iPointSize; i++ )
{
int iCurNum = std::upper_bound(dAngles.begin() + i, dAngles.end(), dAngles[i]+dRange) - dAngles.begin() - i ;
iRet = max(iRet, iCurNum);
}
return iRet + iSelfPoints;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法C++ 实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】事务Transaction

1. 事务的概念 事务是什么 在业务逻辑中使用sql&#xff0c;面对一些较复杂的场景&#xff0c;是需要多个sql语句组合起来实现的。如&#xff1a;银行的转账业务&#xff0c;若客户A要转账100元给客户B&#xff0c;就要两条sql&#xff1a;A余额减100&#xff0c;B余额加100&a…

react-router-dom5升级到6

前言 升级前版本为5.1.2 下载与运行 下载 npm install react-router-dom6运行 运行发现报错: 将node_modules删除&#xff0c;重新执行npm i即可 运行发现如下报错 这是因为之前有引用react-router-dom.min&#xff0c;v6中取消了该文件&#xff0c;所以未找到文件导致报错。…

浅谈数字孪生的应用与发展

1、数字孪生概念 ”数字孪生是充分利用物理模型、传感器更新、运行历史等数据,集成多学科、多物理量、多尺度、多概率的仿真过程,在虚拟空间中完成映射,从而反映相对应的实体装备的全生命周期过程。数字孪生是一种超越现实的概念,可以被视为一个或多个重要的、彼此依赖的装…

Kubernetes集群部署Rook Ceph实现文件存储,对象存储,块存储

Kubernetes集群部署Rook Ceph部署Ceph集群 1. Rook Ceph介绍 Rook Ceph是Rook项目中的一个存储方案&#xff0c;专门针对Ceph存储系统进行了优化和封装。Ceph是一个高度可扩展的分布式存储系统&#xff0c;提供了对象存储、块存储和文件系统的功能&#xff0c;广泛应用于提供…

Spring Data Redis对象缓存序列化问题

相信在项目中&#xff0c;你一定是经常使用 Redis &#xff0c;那么&#xff0c;你是怎么使用的呢&#xff1f;在使用时&#xff0c;有没有遇到同我一样&#xff0c;对象缓存序列化问题的呢&#xff1f;那么&#xff0c;你又是如何解决的呢&#xff1f; Redis 使用示例 添加依…

Stable Diffusion WebUI制作光影文字效果

在huggingface上下载control_v1p_sd15_brightness模型。 将模型放在stable-diffusion-webui\extensions\sd-webui-controlnet\models目录下。 SD参数配置 正向提示词&#xff1a; city,Building,tall building,Neon Light, gentle light shines through, anime style, paint…

AI模型训练【偏差/方差】与【欠拟合/过拟合】

在我们拿到一个数据集&#xff0c;高高兴兴准备训练一个模型时&#xff0c;会遇到欠拟合或过拟合的问题&#xff0c;业内也喜欢用偏差和方差这两指标去定义它们&#xff0c;那这些词什么意思呢&#xff1f;有什么方法能避免/解决 欠拟合和过拟合呢&#xff1f; 这其实是非常非常…

【测试基础】构造测试数据之 MySQL 篇

构造测试数据之 MySQL 篇 作为一名测试工程师&#xff0c;我们经常会构造测试数据进行一些功能验证。为了暴露更多的问题&#xff0c;在测试数据的构造上&#xff0c;我们应该尽可能的构造不同类型的字段数据&#xff0c;且一张表的字段最好不低于 10 10 10 个。 对于 MySQL …

UDP信号多个电脑的信息传输测试、配置指南

最近要做一个东西&#xff0c;关于一个软件上得到的信号&#xff0c;如何通过连接的局域网&#xff0c;将数据传输出去。我没做过相关的东西&#xff0c;但是我想应该和软件连接数据库的过程大致是差不多的&#xff0c;就一个ip和一个端口号啥的。 一.问题思路 多个设备同时连…

自动化测试系列 之 Python单元测试框架unittest

一、概述 什么是单元测试 单元测试是一种软件测试方法&#xff0c;是测试最小的可测试单元&#xff0c;通常是一个函数或一个方法。 在软件开发过程中&#xff0c;单元测试作为一项重要的测试方法被广泛应用。 为什么需要单元测试 单元测试是软件开发中重要的一环&#xf…

微服务系列之分布式事务理论

概述 事务是由一组操作构成的可靠的独立的工作单元&#xff0c;事务具备ACID的特性&#xff0c;即原子性、一致性、隔离性和持久性。 分类 大多数情况下&#xff0c;分类是没有意义的一件事。但是分类可以一定程度上&#xff0c;加深理解。 实现 从实现角度来看&#xff0…

c语言函数篇——递归函数

递归函数的工作原理 递归函数的工作原理基于两个主要部分&#xff1a;基本情况和递归情况。基本情况是函数不再调用自身的条件&#xff0c;当达到基本情况时&#xff0c;递归停止并返回结果。递归情况是函数调用自身的部分&#xff0c;它将问题分解为更小的、相似的子问题。 …

【Matlab】基于遗传算法优化BP神经网络 (GA-BP)的数据时序预测

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88682033 一&#xff0c;概述 基于遗传算法优化BP神经网络 (GA-BP) 的数据时序预测是一种常用的机器学习方法&#xff0c;用于预测时间序列数据的趋势和未来值。 在使用这种方法之前&#xff0c;需要将时间序…

微信小程序开发系列-07组件

微信小程序开发系列目录 《微信小程序开发系列-01创建一个最小的小程序项目》《微信小程序开发系列-02注册小程序》《微信小程序开发系列-03全局配置中的“window”和“tabBar”》《微信小程序开发系列-04获取用户图像和昵称》《微信小程序开发系列-05登录小程序》《微信小程序…

【FileZilla】的基本使用

一、FileZilla的使用 1.1 FileZilla简介 1.2 软件下载 到官方网站下载 FileZilla 的服务端和客户端程序 FileZilla - The free FTP solution 自行下载即可 1.3 软件安装 &#xff08;1&#xff09;先安装服务端【傻瓜式安装】&#xff0c;一直下一步下一步安装即可 &#xf…

uniapp中组件库的丰富NumberBox 步进器的用法

目录 基本使用 #步长设置 #限制输入范围 #限制只能输入整数 #禁用 #固定小数位数 #异步变更 #自定义颜色和大小 #自定义 slot API #Props #Events #Slots 基本使用 通过v-model绑定value初始值&#xff0c;此值是双向绑定的&#xff0c;无需在回调中将返回的数值重…

【linux】head的用法 输出文件开头的内容

在linux可以用find查找一个文件&#xff0c;可以用grep查找符合要求的文件内容&#xff0c;但是有的时候希望查看文件的前几行或者后几行&#xff08;其实这种场景经常可以遇到&#xff0c;比如接触到日志分析的时候&#xff09;&#xff0c;那就应该使用head和tail这两个工具了…

SpringMVC源码解析——DispatcherServlet初始化

在Spring中&#xff0c;ContextLoaderListener只是辅助功能&#xff0c;用于创建WebApplicationContext类型的实例&#xff0c;而真正的逻辑实现其实是在DispatcherServlet中进行的&#xff0c;DispatcherServlet是实现Servlet接口的实现类。Servlet是一个JAVA编写的程序&#…

STM32——F407定时器概述

1 定时器分类 定时器类型数量位号位宽时钟捕获/比较输出DMA请求计数互补输出基本2TIM6,TIM716bitAPB1-有递增-通用2TIM2,TIM532bitAPB14通道有递增、递减、中心对齐-通用2TIM3,TIM432bitAPB14通道有递增、递减、中心对齐-通用1TIM916bitAPB14通道有递增-通用2TIM10、TIM1116bi…

图像分割实战-系列教程3:unet医学细胞分割实战1(医学数据集、图像分割、语义分割、unet网络、代码逐行解读)

&#x1f341;&#x1f341;&#x1f341;图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 上篇内容&#xff1a; Unet系列算法 下篇内容&#xff1a; unet医学细胞分割实战2 1、医学细胞数据…