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

news2024/11/29 13:31:54

给定一个数组 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());

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

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

相关文章

白鲨优化算法(WSO)的MATLAB代码复现

目录 1 白鲨优化算法优化BP神经网络代码复现 2 白鲨优化算法优化支持向量机代码复现 3 白鲨优化算法优化长短期记忆神经网络代码复现 1 白鲨优化算法优化BP神经网络代码复现 1&#xff09;单输出回归预测&#xff1a;单输出回归预测&#xff1a;大白鲨算法优化BP神经网络模…

OpenCV HoughLine()函数与HoughlinesP()函数及HoughCircles()函数详解及用法示例

OpenCV HoughLine()函数与HoughlinesP()函数都用于图像中的直线检测&#xff0c;但二者是有区别的。 HoughLine()函数 HoughLines&#xff08;&#xff09;基于霍夫变换的原理&#xff0c;通过投票机制来确定图像中直线的存在及其参数。该函数返回检测到的直线的极坐标参数。它…

【多线程】CAS原理

文章目录 为什么会出现CAS思想?CAS概念CAS自旋概念CAS的简单使用CAS源码解析 UnSafe类CAS底层原理CAS的硬件保证CAS自旋锁的实现前置知识----原子引用AtomicReference实现自旋锁 CAS缺点ABA问题什么是ABA问题如何解决ABA问题简单案例AtomicStampedReference的源码分析 为什么会…

leetcode链表(二)-两两交换链表中的节点

题目 . - 力扣&#xff08;LeetCode&#xff09; 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 思路 一定要使用虚拟头节点…

电子学报期刊投稿过程记录

电子学报的编辑老师确实人非常好&#xff0c;专业知识过硬&#xff0c;文章内容审核仔细&#xff0c;对格式的要求相对严格&#xff0c;并且打电话或者邮箱询问都很和善&#xff0c;也很温柔&#xff0c;同时也愿意配合再缴费后提前发送录用证明&#xff0c;但是见刊和网络首发…

单点登录Apereo CAS 7.1客户端集成教程

从上一篇部署并成功运行CAS服务端后,我们已经能通过默认的账号密码进行登录。 上篇地址:单点登录Apereo CAS 7.1安装配置教程-CSDN博客 本篇我们将开始对客户端进行集成。 CAS中的客户端,就是指我们实际开发的各个需要登录认证的应用。现在,跟着笔者的步伐,一起探索如何…

共识算法Raft

引入 在分布式系统中&#xff0c;为了消除单点提高系统可用性&#xff0c;通常会创建副本来进行容错&#xff0c;但这会带来另一个问题就是&#xff0c;如何保证多个副本之间的数据一致性。 为了解决这个问题&#xff0c;计算机行内就提出了共识算法&#xff0c;它允许多个分…

git gui基本使用

一、图形化界面 二、创建新项目 创建文件&#xff0c;加入暂存区&#xff0c;提交到版本库 三、创建分支 四、合并分支 1.切换至master 五、更新分支 六、解决冲突 修改冲突&#xff0c;加入暂存区&#xff0c;提交到版本库 七、远程创建库 Gitee - 基于 Git 的代码托管和研…

低功耗

低功耗 目录 低功耗 STM32中的电源系统 STM32 中的低功耗 相关代码 -- 首先我们先看我们做的项目如何降低功耗 -- 对于设备&#xff0c;功耗怎么降低&#xff1f;把设备上所有的电子模块&#xff0c;都进入低功耗模式。 对于空气质量检测仪&#xff0c;如何降低功耗&…

修改armbian DNS服务器地址(永久修改DNS配置)

linux dns服务器地址的配置文件在/etc/resolv.conf 但系统可能设置的是默认值&#xff0c;也就是192.168.1.1。导致系统无法正常解析域名&#xff0c;进而导致有一些接口无法调用或下载失败。 最直接的思路就是修改/etc/resolv.conf&#xff0c;将其中的nameserver修改为正确的…

必看系列:面试官通过一个问题考查了网络编程所有知识点!

一、写在开头 本文的主题是和大家一起探讨学习:“在浏览器中输入URL开始后,计算机所做的几件事”,这个问题是好几年前自己面试的时候,面试官考问过的,当时准备十分不充分,回答的一塌糊涂,今天拿出来再整理学习一遍,一同进步! 其实这个问题本身倒是不难,但它巧妙的是…

节假日提醒,节假日任务,节假日判断如何做?这篇文章教会你!

你是否有这样的需求&#xff0c;有一个任务需要在大家都休息的时候处理&#xff0c;你肯定会想到周六周日了&#xff0c;那不好意思&#xff0c;遇到调休怎么办呢&#xff1f;遇到国假怎么办呢&#xff1f;我这里所说的节假日和工作日不仅仅指正常的周一至周日&#xff0c;还包…

浙江省发规院产业发展研究所调研组莅临迪捷软件考察调研

2024年10月10日下午&#xff0c;浙江省发展与规划院产业发展研究所调研组一行莅临迪捷软件考察调研&#xff0c;绍兴市府办、区发改、区经信、迪荡街道等相关领导陪同。 调研组一行参观了迪捷软件的展厅与办公区&#xff0c;深入了解了迪捷软件的公司发展历程、运营状况、产品…

Python 如何使用 Bert 进行中文情感分析

前言 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;情感分析是一个非常常见且重要的应用。情感分析通常用于识别文本中的情感&#xff0c;例如判断一条微博或评论是正面、负面还是中性。在过去的几年中&#xff0c;随着深度学习的发展&#xff0c;BERT&#xff…

MySQL表的基本操作和数据类型

MySQL表的基本操作和数据类型 表的操作创建表修改表删除表 数据类型数值类型整型浮点型 文本、二进制类型日期时间类型ENUM类型和SET类型 表的操作 创建表 语法&#xff1a; CREATE TABLE table_name(field1 datatype,field2 datatype,field3 datatype )character set 字符集…

Python的matplotlib可视化工具基本操作(数据分析生成图表)

一、安装导入 1、使用包管理器安装matplotlib pip3 install matplotlib 2、导入plt工具 import matplotlib.pyplot as plt 二、基本函数 1、创建图表 使用pyplot工具打点调用创建图表函数 例如创建直方图&#xff1a; import matplotlib.pyplot as plt import pandas…

【unity框架开发9】序列化字典,场景,vector,color,Quaternion

文章目录 前言一、可序列化字典类普通字典简单的使用可序列化字典简单的使用 二、序列化场景三、序列化vector四、序列化color五、序列化旋转Quaternion完结 前言 自定义序列化的主要原因&#xff1a; 可读性&#xff1a;使数据结构更清晰&#xff0c;便于理解和维护。优化 I…

Android Framework默认授予app通知使用权限

安卓通知使用权限 在安卓系统中&#xff0c;应用程序需要获取通知使用权限才能向用户发送通知。以下是关于安卓通知使用权限的一些信息&#xff1a; 权限获取方式 当用户安装应用时&#xff0c;系统可能会在安装过程中提示用户授予应用通知权限。用户可以选择允许或拒绝。 应…

记录一些yolo-world训练数据集的报错

参考的这个文章 https://blog.csdn.net/ITdaka/article/details/138863017?spm1001.2014.3001.5501 openai快捷下载&#xff1a;https://download.csdn.net/download/qq_43767886/89876720 然后我打算训练coco数据集&#xff0c;遇到了以下的问题 问题一 原因&#xff1a;…

智慧农田新篇章:高标准农田灌区信息化的创新实践

在新时代的农业发展蓝图中&#xff0c;智慧农田已成为推动农业现代化、实现可持续发展目标的关键一环。高标准农田灌区信息化作为智慧农业的重要组成部分&#xff0c;正引领着一场深刻的农业技术革命&#xff0c;它不仅关乎粮食安全与资源高效利用&#xff0c;还深刻影响着农村…