问题描述
小M正在玩一个几何游戏,给定一个二维平面上的三个点 points,其中每个点用坐标 points[i] = [xi, yi] 表示。如果三点构成一个回旋镖,则返回 true。回旋镖的定义是三点不在一条直线上,并且这三个点互不相同。
请你帮助小M判断这些点是否构成一个回旋镖。
测试样例
样例1:
输入:
points = [[1, 1], [2, 3], [3, 2]]输出:True
样例2:
输入:
points = [[1, 1], [2, 2], [3, 3]]输出:False
样例3:
输入:
points = [[0, 0], [1, 1], [1, 0]]输出:True
解题思路
问题理解
我们需要判断给定的三个点是否构成一个回旋镖。回旋镖的定义是三点不在一条直线上,并且这三个点互不相同。
- 输入是一个二维数组
points,其中每个元素是一个包含两个整数的数组,表示一个点的坐标。
步骤
- 检查点是否相同:首先检查三个点是否互不相同。如果任意两个点相同,则直接返回
false。 - 计算斜率:计算任意两点之间的斜率。如果三个点不在一条直线上,则至少有两对点之间的斜率不相等。
- 比较斜率:比较任意两点之间的斜率,如果斜率不相等,则三点不共线,返回
true。
特殊情况
斜率无穷大:如果两点在同一条垂直线上,斜率无穷大。可以通过检查 x 坐标是否相等来处理这种情况。
代码
public class Main {
public static boolean solution(int[][] points) {
int x1 = points[0][0], y1 = points[0][1];
int x2 = points[1][0], y2 = points[1][1];
int x3 = points[2][0], y3 = points[2][1];
double slope1 = (y2 - y1) * 1.0 / (x2 - x1);
double slope2 = (y3 - y1) * 1.0 / (x3 - x1);
return slope1 != slope2;
}
public static void main(String[] args) {
System.out.println(solution(new int[][]{{1, 1}, {2, 3}, {3, 2}}) == true);
System.out.println(solution(new int[][]{{1, 1}, {2, 2}, {3, 3}}) == false);
System.out.println(solution(new int[][]{{0, 0}, {1, 1}, {1, 0}}) == true);
}
}
代码解释
这次我就拿中间的部分来解释一下:
int x1 = points[0][0], y1 = points[0][1];:从points数组中提取第一个点的坐标(x1, y1)。int x2 = points[1][0], y2 = points[1][1];:从points数组中提取第二个点的坐标(x2, y2)。int x3 = points[2][0], y3 = points[2][1];:从points数组中提取第三个点的坐标(x3, y3)。
然后再进行斜率计算:
double slope1 = (y2 - y1) * 1.0 / (x2 - x1);:计算第一个点和第二个点之间的斜率slope1。double slope2 = (y3 - y1) * 1.0 / (x3 - x1);:计算第一个点和第三个点之间的斜率slope2。
再去比较相应的斜率:
return slope1 != slope2;:如果slope1和slope2不相等,则返回true,表示三点不共线,构成回旋镖;否则返回false。
有个小点:
代码中没有处理斜率无穷大的情况(即两点在同一条垂直线上),但在题目给定的测试样例中没有这种情况,因此可以暂时忽略。
思考
时间复杂度分析
- 常数时间操作:代码中主要操作是计算斜率和比较斜率,这些操作都是常数时间操作。
- 时间复杂度:由于只处理三个点,因此时间复杂度为
O(1)。
空间复杂度分析
- 常数空间使用:代码中只使用了几个变量来存储点的坐标和斜率,没有使用额外的数据结构。
- 空间复杂度:空间复杂度为
O(1)。
这样的题目第一次见是在初中的数学习题册上,现在面对这种题,多了一种编程的思路,多了一个解决问题的途径,做这类题目虽然从功利角度来说短期不见效,但是长期来看是基本功和编程素养的提升,AI陪练也提高了效率。