用最短长度的绳子把整个花园围起来

给定一个数组 trees,其中 trees[i] = [xi, yi] 表示树在花园中的位置。

你被要求用最短长度的绳子把整个花园围起来,因为绳子很贵。只有把 所有的树都围起来,花园才围得很好。

返回恰好位于围栏周边的树木的坐标

示例 1:

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

示例 2:

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

class Solution {
public:
    vector<vector<int>> outerTrees(vector<vector<int>>& trees) {
        // 如果树的数量小于等于 1,直接返回
        if (trees.size() <= 1) return trees;

        // 自定义比较函数
        auto cmp = [](vector<int>& p1, const vector<int>& p2) {
            return p1[0] < p2[0] || (p1[0] == p2[0] && p1[1] < p2[1]);
        };

        sort(trees.begin(), trees.end(), cmp);

        // 构建下凸包
        vector<vector<int>> lower;
        for (auto& tree : trees) {
            while (lower.size() >= 2 && cross(lower[lower.size() - 2], lower.back(), tree) < 0) {
                lower.pop_back();
            }
            lower.push_back(tree);
        }

        // 构建上凸包
        vector<vector<int>> upper;
        for (int i = trees.size() - 1; i >= 0; i--) {
            auto& tree = trees[i];
            while (upper.size() >= 2 && cross(upper[upper.size() - 2], upper.back(), tree) < 0) {
                upper.pop_back();
            }
            upper.push_back(tree);
        }

        vector<vector<int>> result(lower);
        result.insert(result.end(), upper.begin(), upper.end());
        
        set<vector<int>> res(result.begin(), result.end());// 去掉重复的点
        
        return vector<vector<int>>(res.begin(),res.end());//返回vector<vector<int>>类型
    }


    // 计算叉积
    int cross(vector<int>& O, vector<int>& A, vector<int>& B) {
        return (A[0] - O[0]) * (B[1] - O[1]) - (A[1] - O[1]) * (B[0] - O[0]);
    }
};

auto cmp = [](vector<int>& p1, const vector<int>& p2) {

            return p1[0] < p2[0] || (p1[0] == p2[0] && p1[1] < p2[1]);

        };

这个比较函数用于根据树木的位置对它们进行排序。首先按 x 坐标排序,如果 x 坐标相同,则按 y 坐标排序。

叉积 A×B=Ax​⋅By​−Ay​⋅Bx​ 可以帮助判断三点之间的相对方向。给定三点 O(原点)、A 和 B,叉积的结果可以用来判断 A 和 B 相对于 O 的位置关系:

  • 正数:表示 B 在 A 的左侧,形成的角度是逆时针(O -> A -> B 是一个左转)。
  • 负数:表示 B 在 A 的右侧,形成的角度是顺时针(O -> A -> B 是一个右转)。
  • :表示 A 和 B 在同一条直线上。

构建凸包:

while (lower.size() >= 2 && cross(lower[lower.size() - 2], lower.back(), tree) < 0)

构建下凸包时,必须要保证有至少两个点,才能进行三点之间的相对方向判断。while 循环可以确保我们在引入每一个新点时,能够动态地调整 lower 中的点,以确保所有点都能形成一个外包围的凸形结构。

举个例子:第一个点 [1, 1]

加入 lower,当前 lower = [[1, 1]]

第二个点 [2, 0]

加入 lower,当前 lower = [[1, 1], [2, 0]]

第三个点 [3, -1]

现在 lower.size() == 2,计算叉积:

cross([1, 1], [2, 0], [3, -1])

(2 - 1) * (-1 - 1) - (0 - 1) * (3 - 2) = 1 * (-2) - (-1) * 1 = -2 + 1 = -1

叉积为负数,说明这三个点构成了 顺时针方向,这通常意味着形成了一个凹形。因此,进入 while 循环,移除 [2, 0],然后再将 [3, -1] 加入 lower

lower 最终包含的是所有位于下边界上的点,这些点构成了围绕给定树木坐标的下半部分的凸包。具体来说,lower 会包含从最左侧的点到最右侧的点,形成一个向上的弯曲结构。

upper 构建上凸包。代码的逻辑与构建下凸包的过程相似,但它从树木坐标的最后一个点开始逆序遍历,直到第一个点。

最后将将 lowerupper 两个 vector 合并为一个新的 vector

result.insert(result.end(), upper.begin(), upper.end());

  • result.end() 表示插入的位置是 result 的末尾。
  • upper.begin()upper.end() 表示要插入的元素范围,即从 upper 的起始位置到结束位置。

set 去重:去除upper和lower重复的部分

set<vector<int>> res (result.begin(), result.end());  在构造过程中,set 会自动去除 result 中的重复元素,只保留唯一的元素

由于set 的返回值类型与 vector 不同。是set<vector<int>>,而我们需要的是vector<vector<int>>,所以最后 return vector<vector<int>>(res.begin(),res.end());

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

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

相关文章

MySQL 的数据类型

1.整数类型 1.1 tinyint tinyint 为小整数类型&#xff0c;存储空间为1个字节&#xff08;8位&#xff09;&#xff0c;有符号范围-128 ~ 127&#xff0c;无符号范围 0 ~ 255,此类型通常在数据库中表示类型的字段&#xff0c;如某一字段 type 表示学科,其中 “type1” 表示语文…

实战篇:(二)React 创建项目并连接 MySQL 后台的实战教程

React 创建项目并连接 MySQL 后台的实战教程 一、项目概述 本篇博客将介绍如何使用 React 搭建前端项目&#xff0c;并通过 Node.js 和 MySQL 实现简单的后台数据连接。通过这个项目&#xff0c;你将掌握从前端到后端数据库的基础开发流程&#xff0c;适合初学者或正在项目实…

中国各大一线及二线省会城市程序员收入大比拼,看看你所在的城市的统计是否准确

在中国&#xff0c;程序员的收入因城市、经验、学历等因素而有所不同。本文将对一线及二线省会城市的程序员收入进行详细比较&#xff0c;帮助大家了解各地的薪资水平。 一线城市程序员收入 上海 上海作为中国的经济中心&#xff0c;程序员收入最高。根据最新数据&#xff…

新生编程入门的方式探讨

关于如何编程入门&#xff0c;这是一个很好的问题。在上大学之前&#xff0c;并没有怎么接触电脑的我&#xff0c;也许可以谈一谈。 还记得在高中的时候&#xff0c;因为很多同学去网吧玩电脑打游戏&#xff0c;被学校开除&#xff0c;老师谆谆教诲大家不要去网吧&#xff0c;所…

Word粘贴时出现“文件未找到:MathPage.WLL”的解决方案

解决方案 一、首先确定自己电脑的位数&#xff08;这里默认大家的电脑都是64位&#xff09;二、右击MathType桌面图标&#xff0c;点击“打开文件所在位置”&#xff0c;然后分别找到MathPage.WLL三、把这个文件复制到该目录下&#xff1a;C:\Program Files\Microsoft Office\r…

SQLAlchemy入门:详细介绍SQLAlchemy的安装、配置及基本使用方法

SQLAlchemy是一个流行的Python SQL工具包和对象关系映射&#xff08;ORM&#xff09;框架&#xff0c;它为开发人员提供了一种高效、灵活的方式来与数据库进行交互。本文将详细介绍SQLAlchemy的安装、配置及基本使用方法&#xff0c;并通过代码示例和案例分析&#xff0c;帮助新…

SSL---SSL certificate problem

0 Preface/Foreword 0.1 SSL certificate problem 开发过程中&#xff0c;gitlab-runner连接gitlab时候出现SSL 证书问题。 场景&#xff1a;公司的gitlab runner服务器引入了SSL证书&#xff0c;每年都会主动更新一次。当前的gitlab-runner运行在PC机器上&#xff0c;但是g…

论文翻译 | OpenICL: An Open-Source Framework for In-context Learning

摘要 近年来&#xff0c;上下文学习&#xff08;In-context Learning&#xff0c;ICL&#xff09;越来越受到关注&#xff0c;并已成为大型语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;评估的新范式。与传统微调方法不同&#xff0c;ICL无需更新任何参…

如何用好 CloudFlare 的速率限制防御攻击

最近也不知道咋回事儿,群里好多站长都反映被CC 攻击了。有人说依旧是 PCDN 干的,但明月感觉不像,因为有几个站长被 CC 攻击都是各种动态请求(这里的动态请求指的是.php 文件的请求)。经常被攻击的站长们都知道,WordPress /Typecho 这类动态博客系统最怕的就是这种动态请求…

C++模板初阶,只需稍微学习;直接起飞;泛型编程

&#x1f913;泛型编程 假设像以前交换两个函数需要&#xff0c;函数写很多个或者要重载很多个&#xff1b;那么有什么办法实现一个通用的函数呢&#xff1f; void Swap(int& x, int& y) {int tmp x;x y;y tmp; } void Swap(double& x, double& y) {doubl…

【自然语言处理】多头注意力Multi-Head Attention机制

多头注意力&#xff08;Multi-Head Attention&#xff09;机制是Transformer模型中的一个关键组件&#xff0c;广泛用于自然语言处理任务&#xff08;如机器翻译、文本生成等&#xff09;以及图像处理任务。它的核心思想是通过多个不同的注意力头来捕获输入的不同特征&#xff…

MedSAM2调试安装与使用记录

目录 前言一、环境准备多版本cuda切换切换cuda版本二 安装CUDNN2.1 检查cudnn 二、使用步骤1.安装虚拟环境2.测试Gradio3.推理 总结 前言 我们在解读完MedSAM之后&#xff0c;迫不及待想尝尝这个技术带来的福音&#xff0c;因此验证下是否真的那么6。这不&#xff0c;新鲜的使…

使用 KVM 在 Xubuntu 上创建 Windows 10 虚拟机

目录 前言说明注意准备 iso官网思博主(嘻嘻)拖动到虚拟机里面启动 virt-manager创建虚拟机选择本地安装介质选择 iso配置 内存 和 CPU选择 创建的虚拟机 保存的位置启动虚拟机看到熟悉的 Win10界面点击现在安装点击我没有产品密钥选择 Win10 专业工作站版勾选接受许可条款选择自…

《智慧博物馆:科技与文化的完美融合》

《智慧博物馆&#xff1a;科技与文化的完美融合》 一、智慧博物馆的兴起与发展 随着科技的飞速发展&#xff0c;智慧博物馆应运而生。进入新时代&#xff0c;大数据、人工智能、信息化的进步以及智能产品的应用&#xff0c;改变了人们接收信息和学习的习惯。为顺应社会变革&am…

【超详细】UDP协议

UDP传输层协议的一种&#xff0c;UDP(User Datagram Protocol 用户数据报协议)&#xff1a; 传输层协议无连接不可靠传输面向数据报 UDP协议端格式 定长报头&#xff0c;8字节源端口号和目的端口号来定位16位UDP长度, 表示整个数据报(UDP首部UDP数据)的最大长度如果校验和出错…

【C++】线程库常用接口

1.创建线程&#xff0c;等待线程&#xff0c;获取线程id 2.全局变量&#xff0c;局部变量&#xff0c;互斥锁 要让不同的线程访问同一个变量和同一把锁&#xff0c;有两种方法&#xff1a; 2.1方法一 定义全局的变量和全局的锁&#xff0c;这样自然就能访问到。 但全局变量在…

电能表预付费系统-标准传输规范(STS)(5)

5.5MeterFunctionObjects / companion specifications配套规格 With reference to Figure 1 it can be seen that the TokenCarrierToMeterInterface, which also includes the TokenCarrier, is dealt with in the IEC 62055-4x and IEC 62055-5x series. The remaining Mete…

论文 | OpenICL: An Open-Source Framework for In-context Learning

主要内容&#xff1a; 2. 提供多种 ICL 方法&#xff1a; 3. 完整的教程&#xff1a; 4. 评估和验证&#xff1a; 背景&#xff1a; 随着大型语言模型 (LLM) 的发展&#xff0c;上下文学习 (ICL) 作为一种新的评估范式越来越受到关注。问题&#xff1a; ICL 的实现复杂&#xf…

[ABC367C] Enumerate Sequences

1.注意输入的是哪个数组&#xff0c;输出的是哪个 2.dfs函数可以带两个参数&#xff0c;方便记录&#xff0c;一个记录第几个位置&#xff0c;一个记录题目的要求&#xff0c;例如求和。 3.注意递归出口输出后一定要return. #include<bits/stdc.h> using namespace std; …

Unity XR PICO 手势交互 Demo APK

效果展示 用手抓取物体&#xff0c;调整物体位置和大小等 亲测pico4 企业版可用&#xff0c; 其他设备待测试 下载链接&#xff1a; 我标记的不收费 https://download.csdn.net/download/qq_35030499/89879333