路径交叉
难度:
标签:
题目描述
给你一个整数数组 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 次移动与第 i-3 次移动可能相交的情况,具体是如何判断这种相交情况的?能否详细解释判断条件的逻辑?
▷🦆
您在实现中提到`distance[i] >= distance[i - 2] - distance[i - 4]`这个条件,这个表达式具体是基于什么样的几何关系或逻辑得出的?
▷🦆
在处理距离数组 `distance` 时,你是如何处理数组长度小于4的情况的?在代码中似乎没有看到相关的边界处理。
▷