当前位置: 首页 > news >正文

分治算法之凸包问题

1. 算法思路

基本思想

利用分治策略解决凸包问题主要分为两大步骤:

  1. 分解(Divide):

    • 将所有点按照 x 坐标排序,并将点集分为左右两部分。

    • 递归地对左右两部分分别求解凸包。

  2. 合并(Conquer/Merge):

    • 合并左右两个凸包序列。

    • 利用Graham-scan算法得到新的凸包序列。

理论推导

  1. 递归求解:

    • 若点集规模较小(例如 2 或 3 个点),直接用简单方法(如暴力法或旋转卡壳)求解凸包。

    • 否则,将点集分成左右两部分,各自递归求解。设左右部分的凸包分别为 CH_LCH_R​。

  2. 合并过程的理论依据: 利用Graham-scan算法,按照顺序合并为一个新的凸包。


2. 时间复杂度推导

  1. 预排序:
    对所有点按照 x 坐标排序需要 O(nlog⁡n) 。

  2. 递归分解与合并:

    • 分解阶段:每次将点集分为两半,递归求解左右凸包。

    • 合并阶段:对于两个凸包的合并,在线性时间内完成,即 O(n) (实际与左右凸包的点数有关,总体不超过 n )。

    • 由递归关系可得:

      T(n) = 2T\left(\frac{n}{2}\right) + O(n)

      根据主定理可知,该递归式的解为 T(n) = O(n \log n)

  3. 总时间复杂度:
    综合排序与递归合并,总体时间复杂度为 O(nlog⁡n) 。


3. 算法步骤

预处理

  1. 排序:
    将所有点按照 x 坐标(若 x 坐标相同则按 y 坐标)排序,得到有序点集。

递归分治过程

  1. 递归分解:

    • 如果点集大小小于等于 3,直接计算凸包(例如用暴力法或直接返回有序点的极值构成凸包);

    • 否则,将点集分为左右两部分,分别递归求解左侧凸包 CH_L和右侧凸包 CH_R

合并过程

  1. 合并左右两个凸包序列。
  2. 利用Graham-scan算法得到新的凸包序列。

结束

  1. 返回结果:
    递归回溯过程中,每次合并后的凸包传递上层,最终返回整体点集的凸包。


总结

  • 分治策略: 先排序,再递归分解,再合并局部凸包。

  • 理论推导: 归纳了递归求解与合并过程的正确性,并证明合并过程的时间复杂度为 O(n) 。

    • 总时间复杂度: O(nlog⁡n) 

  • 关键步骤: 利用Graham-scan算法是合并阶段的核心,通过不断调整候选点保证最终合并的凸包是最优解。

相关文章:

  • 解决ant-ui 表单校验通过但是未清楚校验提示的bug 示例
  • LeetCode算法题(Go语言实现)_21
  • 《C++知识点之拷贝构造函数》
  • Linux系统安装MySQL 8.0完整指南(新手友好版)
  • 小智机器人关键函数解析:MqttProtocol::SendAudio()对输入的音频数据进行加密处理,通过UDP发送加密后的音频数据
  • spring boot前后端开发上传文件时报413(Request Entity Too Large)错误的可能原因及解决方案
  • 统计局数据分析网站基于Spring Boot SSM原创
  • 各种环境下安装软件的命令对比与总结
  • 算法导论(动态规划)——简单多状态
  • Docker学习--容器操作相关命令--docker wait 命令
  • k8s EmptyDir(空目录)详解
  • C#测试Excel开源组件ExcelDataReader
  • 为什么可视化大屏越来越多应用3D元素呢?
  • Android 11.0 framework中增加开启和关闭飞行模式的接口
  • 使用Redis实现轻量级消息队列
  • C++位运算精要:高效解题的利器
  • Elasticsearch笔记
  • 一个极简的词法分析器实现
  • OpenCV 图形API(6)将一个矩阵(或图像)与一个标量值相加的函数addC()
  • Pycharm(十一):字符串练习题
  • 生物医药网站建设/广州seo推广服务
  • net 网站开发/数据分析师培训机构推荐
  • 聊城网站推广软件/seo推广岗位职责
  • 青海 网站开发 app/全球搜索引擎入口
  • php网站优化/腾讯企点qq
  • 网站建设与管理是什么意思/电商培训