LeetCode 469 凸多边形


文章目录

摘要

《凸多边形》是一道看起来很数学,其实很工程的题。

它不考复杂公式,也不要求你会高等几何,真正的核心只有一个:

所有拐弯方向是不是一致的

如果你写过地图路径、UI 绘制、图形编辑器、甚至简单的碰撞检测,这道题的思想你大概率已经用过,只是没意识到它叫"凸多边形判断"。

描述

题目给你一组点 points,表示一个多边形的顶点,顶点是按顺序给出的(顺时针或逆时针都可以)。

你的任务是判断:

这个多边形是不是 凸多边形

什么是凸多边形,用人话说就是:

  • 任意一条边往内看,不会凹进去
  • 从任意一个顶点转弯,转向方向始终一致
  • 不会出现"左转一下,右转一下"的情况

注意几个隐藏前提:

  • 点的数量 ≥ 3
  • 不需要考虑自交(题目默认是合法多边形)
  • 不要求严格凸(共线允许)

题解答案

这道题的经典解法来自一个非常实用的几何思想:

用叉积判断转向方向

具体思路是:

  1. 对每三个连续的点 (A, B, C)
  2. 计算向量 ABBC 的叉积
  3. 记录叉积的符号(正 or 负)
  4. 只要中途出现方向不一致,立刻返回 false

如果所有拐弯方向都一致,那它一定是凸多边形。

题解代码分析

下面是完整的 Swift 实现,可以直接在 LeetCode 或 Playground 里运行。

swift 复制代码
class Solution {
    func isConvex(_ points: [[Int]]) -> Bool {
        let n = points.count
        if n < 3 { return false }

        var prevCross = 0

        for i in 0..<n {
            let p0 = points[i]
            let p1 = points[(i + 1) % n]
            let p2 = points[(i + 2) % n]

            let cross = crossProduct(p0, p1, p2)

            if cross != 0 {
                if prevCross != 0 && cross * prevCross < 0 {
                    return false
                }
                prevCross = cross
            }
        }

        return true
    }

    private func crossProduct(_ a: [Int], _ b: [Int], _ c: [Int]) -> Int {
        let x1 = b[0] - a[0]
        let y1 = b[1] - a[1]
        let x2 = c[0] - b[0]
        let y2 = c[1] - b[1]
        return x1 * y2 - y1 * x2
    }
}

题解代码分析

为什么用叉积?

叉积在二维空间里有一个非常好用的特性:

  • 结果 > 0 :逆时针转(左转)
  • 结果 < 0 :顺时针转(右转)
  • 结果 = 0 :三点共线

也就是说,它本质是在回答一个问题:

从 A → B → C,是往哪边拐?

为什么只关心"符号",不关心大小?

因为这道题只在乎方向是否一致:

  • 全是左转 → 凸
  • 全是右转 → 凸
  • 左右混着来 → 凹

至于拐得多猛,完全不重要。

为什么要跳过 cross == 0

swift 复制代码
if cross != 0 {
    ...
}

这是为了允许 共线点 的存在。

现实中非常常见,比如:

  • UI 边框上多给了几个点
  • 地图边界是直线拆成多段

只要方向不反转,就依然是凸的。

% n 是干嘛的?

swift 复制代码
points[(i + 1) % n]

这是为了让最后一个点能和第一个、第二个点组成一组,形成一个"闭环"。

多边形一定是闭合的,这一步非常关键。

示例测试及结果

示例 1:凸多边形

swift 复制代码
let solution = Solution()
print(solution.isConvex([[0,0],[0,1],[1,1],[1,0]]))

这是一个标准正方形:

  • 每一次转向方向一致

  • 输出:

    true

示例 2:凹多边形

swift 复制代码
print(solution.isConvex([[0,0],[0,10],[10,10],[5,5],[10,0]]))

中间有一个点明显往里凹:

  • 转向方向发生变化

  • 输出:

    false

时间复杂度

只遍历了一次数组,每次做常数计算:

复制代码
O(n)

空间复杂度

只使用了少量变量,没有额外数据结构:

复制代码
O(1)

总结

《凸多边形》是一道非常值得记住思路的几何题

它教会你的不是几何公式,而是:

  • 如何把"形状判断"转化成"方向一致性判断"
  • 如何用一个简单的数学工具(叉积)解决工程问题
  • 如何写出既严谨又能容忍真实数据噪声的代码
相关推荐
似水明俊德2 小时前
02-C#.Net-反射-面试题
开发语言·面试·职场和发展·c#·.net
无极低码2 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发3 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
superior tigre3 小时前
22 括号生成
算法·深度优先
腾阳4 小时前
99%的人忽视了这一点:活着本身就是人生的意义,别让抑郁和内耗成为你的枷锁!
经验分享·程序人生·职场和发展·跳槽·学习方法·媒体
不吃西红柿的854 小时前
[职场] 内容运营求职简历范文 #笔记#职场发展
笔记·职场和发展·内容运营
liyang_8304 小时前
邦芒秘诀:职场高手都具备的三个特征
职场和发展
普通网友4 小时前
十大秘闻:揭秘霍兰德职业兴趣理论的未知面!
职场和发展·求职招聘·职场发展·单一职责原则
爱我所爱flash4 小时前
职场上,如果不想被淘汰,谨记这3条生存法则,早知早获益
职场和发展
程序员雨果4 小时前
软件测试工程师:面试题与经验分享
软件测试·面试·职场和发展