把三角形染成红色
难度:
标签:
题目描述
代码结果
运行时间: 98 ms, 内存: 51.4 MB
/*
* 思路:
* 1. 使用 Java Stream API 处理数据。
* 2. 与传统方法相同,使用 stream 进行点和三角形的检查。
*/
import java.util.stream.Stream;
public class Solution {
public static void main(String[] args) {
int[][] points = {{0, 0}, {5, 0}, {0, 5}};
int[] pointToCheck = {2, 2};
boolean isInside = isPointInTriangle(points, pointToCheck);
System.out.println("The point is inside the triangle: " + isInside);
}
// 检查三个点是否能形成一个三角形
public static boolean isTriangle(int[] p1, int[] p2, int[] p3) {
return Stream.of(p1, p2, p3)
.distinct()
.count() == 3 &&
(p2[1] - p1[1]) * (p3[0] - p1[0]) != (p3[1] - p1[1]) * (p2[0] - p1[0]);
}
// 计算一个点是否在三角形内部
public static boolean isPointInTriangle(int[][] triangle, int[] point) {
int[] p1 = triangle[0];
int[] p2 = triangle[1];
int[] p3 = triangle[2];
double denominator = ((p2[1] - p3[1]) * (p1[0] - p3[0]) + (p3[0] - p2[0]) * (p1[1] - p3[1]));
double a = ((p2[1] - p3[1]) * (point[0] - p3[0]) + (p3[0] - p2[0]) * (point[1] - p3[1])) / denominator;
double b = ((p3[1] - p1[1]) * (point[0] - p3[0]) + (p1[0] - p3[0]) * (point[1] - p3[1])) / denominator;
double c = 1 - a - b;
return Stream.of(a, b, c).allMatch(coefficient -> coefficient >= 0 && coefficient <= 1);
}
}
解释
方法:
该题解的核心思路是根据给定的三角形的大小(size),使用一个列表(res)来存储需要被染红的三角形格子的坐标。如果三角形的大小小于4,直接返回一个预设的列表,包含较小三角形的坐标。对于大于等于4的大小,该解决方案遍历每一行,并根据当前行与最大行数之差的模4结果来决定该行哪些位置的坐标需要添加到结果列表中。具体来说,模数结果为0时,添加整行的所有坐标;为1时,添加第二个位置的坐标;为2时,从第二个位置开始添加后面的所有坐标;为3时,只添加第一个位置的坐标。这种方法通过模数操作确定每行需要染红的格子,从而避免了复杂的条件判断或额外的数据结构。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中,对于三角形的大小小于4时直接返回预设列表的逻辑是如何确定的?这些坐标具体代表什么意义?
▷🦆
题解中提到的模4操作用于决定每行哪些位置的坐标需要添加,能否解释其背后的逻辑或模式是如何与三角形的绘制相关联的?
▷🦆
为何在处理大于等于4的三角形大小时,初始化结果列表时只添加了`[1, 1]`,这个坐标点有什么特殊的意义吗?
▷🦆
在计算模数结果并添加坐标时,如何确定这些坐标正好能覆盖整个三角形的需要染红的部分,而不是遗漏或重复染色?
▷