leetcode
leetcode 301 ~ 350
路径交叉

路径交叉

难度:

标签:

题目描述

给你一个整数数组 distance

X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说,每次移动后你的方位会发生逆时针变化。

判断你所经过的路径是否相交。如果相交,返回 true ;否则,返回 false

 

示例 1:

输入:distance = [2,1,1,2]
输出:true

示例 2:

输入:distance = [1,2,3,4]
输出:false

示例 3:

输入:distance = [1,1,1,1]
输出:true

 

提示:

  • 1 <= distance.length <= 105
  • 1 <= distance[i] <= 105

代码结果

运行时间: 36 ms, 内存: 22.7 MB


/*
题目思路:
对于使用Java Stream,我们可以先将数组转换成Stream流,然后通过依次移动并检查路径是否交叉。由于Stream是对数据进行连续的操作,因此我们需要将移动后的坐标通过累积方式求出并检查是否发生了交叉。尽管Stream的优势在于处理和转换数据,但对于这种需要中间状态的任务,其优势有限。
*/
 
import java.util.stream.IntStream;
 
public class Solution {
    public boolean isSelfCrossing(int[] distance) {
        if (distance.length < 4) return false;
        return IntStream.range(3, distance.length).anyMatch(i -> (
            // 第 1 种情况
            (distance[i] >= distance[i - 2] && distance[i - 1] <= distance[i - 3]) ||
            // 第 2 种情况
            (i >= 4 && distance[i - 1] == distance[i - 3] && distance[i] + distance[i - 4] >= distance[i - 2]) ||
            // 第 3 种情况
            (i >= 5 && distance[i - 2] >= distance[i - 4] && distance[i] + distance[i - 4] >= distance[i - 2] && distance[i - 1] <= distance[i - 3] && distance[i - 1] + distance[i - 5] >= distance[i - 3])
        ));
    }
}

解释

方法:

这个题解的思路是模拟路径,判断是否会出现路径相交的情况。具体分为以下几步: 1. 先处理第一种情况,即一直向外扩张的螺旋路径,直到第i次移动小于等于第i-2次移动,说明开始向内收缩,有可能出现相交。 2. 再处理第i次移动和第i-3次移动组成的矩形区域。如果第i次移动距离等于第i-2次移动距离,或者大于等于第i-2次移动距离减去第i-4次移动距离,说明会与第i-3次移动路径相交。需要将第i-1次移动减去第i-3次移动。 3. 最后处理第二种情况,即处理后续的移动,看是否会出现第i次移动小于第i-2次移动的情况,如果出现则说明路径相交。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中,您是如何确定只考虑到第 i-4 次移动即可判断所有可能的交叉情况?是否存在需要考虑更早移动的情况?
在解析路径交叉问题时,只考虑到第i-4次移动的原因是基于路径的走向。一个螺旋形状的路径只需要考虑最近的几次移动来判断是否会交叉。具体来说,第i次移动只可能与第i-3次移动、第i-4次移动和第i-5次移动形成的路径相交。在大多数情况下,只需要考虑到第i-4次移动,因为这能覆盖所有可能的交叉情况。更早的移动,如第i-6次或之前的移动,由于路径的螺旋特性,通常不会与第i次移动产生交叉。
🦆
题解中提到第 i 次移动与第 i-3 次移动可能相交的情况,具体是如何判断这种相交情况的?能否详细解释判断条件的逻辑?
判断第i次移动与第i-3次移动可能相交的情况是基于两者形成的路径的几何位置。如果第i次移动的距离至少与第i-2次移动的距离相等,且第i-2次移动的距离大于或等于第i-4次移动的距离,则第i次移动可能与第i-3次移动的路径相交。这是因为这种情况下第i次移动足够长,可以延伸到或穿过第i-3次移动形成的路径。
🦆
您在实现中提到`distance[i] >= distance[i - 2] - distance[i - 4]`这个条件,这个表达式具体是基于什么样的几何关系或逻辑得出的?
这个条件是基于对路径的几何分析得出的。在螺旋型移动中,第i次移动如果要与第i-3次移动相交,它的长度必须至少达到第i-2次移动的长度减去第i-4次移动的长度。这是因为第i-2次移动和第i-4次移动定义了一个外部边界,第i次移动需要足够长才能穿越这个边界并与第i-3次移动的路径相交。
🦆
在处理距离数组 `distance` 时,你是如何处理数组长度小于4的情况的?在代码中似乎没有看到相关的边界处理。
代码中确实没有明确地处理数组长度小于4的情况。然而,在主循环中,如果数组长度小于4,由于足够的条件分支不会被满足(例如i >= 4),逻辑将自然流向返回`false`,表明不会有交叉。这种处理方式依赖于循环和条件语句的结构,确保在数组长度不足以形成复杂路径时,程序能够正确地判断出不存在交叉。

相关问题