青训营X豆包MarsCode 技术训练营第一课 | 豆包MarsCode AI 刷题

50 阅读3分钟

问题描述

小M正在玩一个几何游戏,给定一个二维平面上的三个点 points,其中每个点用坐标 points[i] = [xi, yi] 表示。如果三点构成一个回旋镖,则返回 true。回旋镖的定义是三点不在一条直线上,并且这三个点互不相同。

请你帮助小M判断这些点是否构成一个回旋镖。

问题分析

这道题的目标是判断二维平面上的三个点是否构成一个回旋镖。回旋镖的定义为:这三个点不共线且互不相同。

我们可以分两步解决这个问题:

  1. 判断三个点是否互不相同

    • 检查这三个点的坐标是否有重复的情况,如果有重复,则直接返回 False
  2. 判断三个点是否共线

    • 如果三个点在一条直线上,则向量 AB→\overrightarrow{AB} 和 AC→\overrightarrow{AC} 必须平行。通过计算这两个向量的斜率或使用行列式的方法可以判断是否共线。

判断方法

1. 判断点是否重复

直接比较点的坐标,确保所有点两两不相等:

A≠B≠CA \neq B \neq C

2. 判断点是否共线

如果三个点在同一条直线上,计算行列式的方法更简洁。行列式公式如下:

Area=x1(y2−y3)+x2(y3−y1)+x3(y1−y2)\text{Area} = x_1(y_2 - y_3) + x_2(y_3 - y_1) + x_3(y_1 - y_2)

其中 (x1,y1),(x2,y2),(x3,y3)(x_1, y_1), (x_2, y_2), (x_3, y_3) 是三个点的坐标。如果面积为 0,则三个点共线;否则不共线。


实现代码

以下是 Python 的实现:

def is_boomerang(points):
    # 点的坐标
    (x1, y1), (x2, y2), (x3, y3) = points
    
    # 判断点是否互不相同
    if (x1, y1) == (x2, y2) or (x1, y1) == (x3, y3) or (x2, y2) == (x3, y3):
        return False

    # 判断点是否共线 (行列式公式)
    area = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)
    return area != 0

示例测试

示例 1

输入

points = [[1, 1], [2, 3], [3, 2]]

输出

True

解释

  • 点互不相同。
  • 行列式计算面积 1⋅(3−2)+2⋅(2−1)+3⋅(1−3)=1+2−6=−3≠01 \cdot (3 - 2) + 2 \cdot (2 - 1) + 3 \cdot (1 - 3) = 1 + 2 - 6 = -3 \neq 0,点不共线。

示例 2

输入

points = [[1, 1], [2, 2], [3, 3]]

输出

False

解释

  • 点互不相同。
  • 行列式计算面积 1⋅(2−3)+2⋅(3−1)+3⋅(1−2)=−1+4−3=01 \cdot (2 - 3) + 2 \cdot (3 - 1) + 3 \cdot (1 - 2) = -1 + 4 - 3 = 0,点共线。

示例 3

输入

points = [[1, 1], [1, 1], [2, 2]]

输出

False

解释

  • 两个点重复,直接返回 False

时间复杂度与空间复杂度

时间复杂度

  • 判断点是否重复:O(1)O(1)。
  • 计算行列式:O(1)O(1)。
  • 总复杂度:O(1)O(1)。

空间复杂度

  • 常量级存储:O(1)O(1)。

总结

本题的关键在于对点重复检查共线判断的理解与实现:

  1. 使用简单的比较操作检查点是否重复。
  2. 使用行列式方法高效判断共线问题,比直接计算斜率更稳定且避免除法问题。

代码逻辑清晰,复杂度低,适用于不同规模的输入。