leetcode
leetcode 2101 ~ 2150
把三角形染成红色

把三角形染成红色

难度:

标签:

题目描述

代码结果

运行时间: 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的三角形大小,直接返回预设列表是为了处理小规模数据时的特殊情况。这些预设的坐标列表基于小三角形的直观染色模式预先设定。具体的坐标例如[1,1], [2,1], [2,3]等分别代表在一个虚拟的网格中三角形的行和列位置,用于直接指定在三角形的哪些位置上进行染色。这种方法避免了对小三角形进行复杂的算法计算,简化了代码的实现。
🦆
题解中提到的模4操作用于决定每行哪些位置的坐标需要添加,能否解释其背后的逻辑或模式是如何与三角形的绘制相关联的?
模4操作在题解中用于创建一个重复的染色模式,使每四行一循环。这种模式与三角形的绘制相关联,通过不同的模数结果决定每行如何染色。具体来说:模数为0时,染整行;模数为1时,仅染第二个位置;模数为2时,从第二个位置开始到行末;模数为3时,仅染第一个位置。这样的分配确保了三角形在视觉上保持一定的规律性和美观性,同时简化了代码的逻辑处理。
🦆
为何在处理大于等于4的三角形大小时,初始化结果列表时只添加了`[1, 1]`,这个坐标点有什么特殊的意义吗?
在实现中,坐标`[1, 1]`代表三角形的顶点。这是大于等于4的三角形的起始点,因此在结果列表初始化时首先添加这个坐标。它作为三角形的最顶端,是构建整个三角形的基础。在之后的行中,根据模4的结果来决定如何添加其他坐标,从而逐步构建出整个三角形。
🦆
在计算模数结果并添加坐标时,如何确定这些坐标正好能覆盖整个三角形的需要染红的部分,而不是遗漏或重复染色?
通过精心设计的模4逻辑,每种模数结果对应的坐标添加规则确保了坐标的正确添加。这个模式通过行与行之间的关系(每行坐标的增加与行数相关)以及每行内部的坐标增加规则,确保了坐标能够覆盖整个三角形的红色部分。例如,模数为0时添加整行保证了较大面积的连续覆盖,而其他模数结果则在不同位置添加坐标,避免了重复染色的同时也没有遗漏。通过多次测试和验证,这种方法被证实可以有效地覆盖整个三角形。

相关问题