leetcode
leetcode 301 ~ 350
直线镜像

直线镜像

难度:

标签:

题目描述

代码结果

运行时间: 37 ms, 内存: 20.2 MB


/*
 * 题目编号: 356
 * 题目: 直线镜像
 * 题目思路:
 * 给定一些点 (x, y),需要确定是否存在一条垂直于 y 轴的直线,使得这些点关于这条直线是对称的。
 * 具体做法如下:
 * 1. 使用一个集合记录每个点的坐标。
 * 2. 计算所有点的最小和最大 x 坐标,计算它们的平均值 mid_x。
 * 3. 对于每个点 (x, y),检查其关于 mid_x 的对称点 (2 * mid_x - x, y) 是否也在集合中。
 */
 
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
public class Solution {
    public boolean isReflected(int[][] points) {
        if (points == null || points.length == 0) return true;
        Set<String> pointSet = IntStream.range(0, points.length)
                .mapToObj(i -> points[i][0] + "," + points[i][1])
                .collect(Collectors.toSet());
 
        int minX = IntStream.range(0, points.length)
                .map(i -> points[i][0])
                .min()
                .getAsInt();
        int maxX = IntStream.range(0, points.length)
                .map(i -> points[i][0])
                .max()
                .getAsInt();
 
        double midX = (double)(minX + maxX) / 2;
 
        return IntStream.range(0, points.length)
                .allMatch(i -> pointSet.contains((int)(2 * midX - points[i][0]) + "," + points[i][1]));
    }
}
 

解释

方法:

此题解的思路是通过找到所有给定点集的最左和最右的x坐标值,然后计算这两个x值的中点作为可能的对称轴。之后,遍历每一个点,检查其关于中点的对称点是否存在于点集中。如果所有点都符合这一条件,说明点集关于该中线对称;如果任一点的对称点不存在,则不对称。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
题解计算对称轴的方法是找到最左和最右的x坐标的中点。在点集非常大的情况下,这种方法是否可能导致精度问题?如果是,如何解决?
在处理非常大的点集时,确实可能出现精度问题,尤其是在使用浮点数进行中点计算时。由于浮点数的精度限制,当x坐标的数值非常大或非常接近时,计算中点可能导致轻微的偏差,影响后续的对称性检查。一种可能的解决方案是使用整数运算代替浮点运算。例如,可以将中点计算公式改为使用整数除法 `(l + r) // 2` 或者维持 `(l + r) / 2` 但在检查对称点时四舍五入到最接近的整数。这样可以减少由浮点数引入的误差。
🦆
题解假设了点集中所有点的y坐标对于对称性没有影响,只考虑了x坐标。实际上对于y坐标的处理是否也需要考虑,以确保完全的对称性?
实际上,题解中确实考虑了y坐标的对称性。在检查每个点的对称点是否存在于集合中时,对称点的计算包括了y坐标(即检查点 `(2 * m - x, y)` 是否存在)。这意味着对于每个点 `(x, y)`,不仅x坐标需要对称,y坐标也必须完全相同。因此,题解已经确保了在x轴和y轴上都进行了对称性检查,这是检查点集是否关于某一垂直线对称的正确方法。
🦆
在题解的实现中,如果点集为空,或者所有点的x坐标相同,这种特殊情况下的返回值应该是什么?代码中是否有处理这种情况?
在题解的实现中,如果点集为空,应该返回True,因为从集合论的角度看,空集是对称的。同样,如果所有点的x坐标相同,也应该返回True,因为所有这些点本质上都位于同一垂直线上,自然是对称的。当前的代码对于这两种情况都能正确处理:1) 空集情况下,`seen` 集合为空,不进入检查循环,直接返回True;2) 所有点x坐标相同的情况下,计算的中点 `m` 将与所有点的x坐标相同,因此对称点检查始终成立,也将返回True。
🦆
如果点集中存在重复的点,题解中的方法是否还能正确判断对称性?如果不能,应该如何修改代码来处理重复点?
如果点集中存在重复的点,题解中的方法仍然能够正确判断对称性。这是因为重复的点在加入 `seen` 集合时自动去重,每个点位置只记录一次。检查对称性时,由于考虑的是位置而非点的个数,所以即便有重复点,只要每个点的对称点也存在于集合中,就能正确地判断出对称性。因此,无需修改代码来特别处理重复点。

相关问题

直线上最多的点数

给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。

 

示例 1:

输入:points = [[1,1],[2,2],[3,3]]
输出:3

示例 2:

输入:points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出:4

 

提示:

  • 1 <= points.length <= 300
  • points[i].length == 2
  • -104 <= xi, yi <= 104
  • points 中的所有点 互不相同

回旋镖的数量

给定平面上 n 互不相同 的点 points ,其中 points[i] = [xi, yi]回旋镖 是由点 (i, j, k) 表示的元组 ,其中 i 和 j 之间的欧式距离和 i 和 k 之间的欧式距离相等(需要考虑元组的顺序)。

返回平面上所有回旋镖的数量。

 

示例 1:

输入:points = [[0,0],[1,0],[2,0]]
输出:2
解释:两个回旋镖为 [[1,0],[0,0],[2,0]][[1,0],[2,0],[0,0]]

示例 2:

输入:points = [[1,1],[2,2],[3,3]]
输出:2

示例 3:

输入:points = [[1,1]]
输出:0

 

提示:

  • n == points.length
  • 1 <= n <= 500
  • points[i].length == 2
  • -104 <= xi, yi <= 104
  • 所有点都 互不相同