给你一个整数数组 distance 。
从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说,每次移动后你的方位会发生逆时针变化。
判断你所经过的路径是否相交。如果相交,返回 true ;否则,返回 false 。
解题思路
根据归纳结果,我们发现当不出现路径交叉时,只可能有以下三种情况:
第 11 种情况:对于每一次移动 ii,第 ii 次移动距离都比第 i-2i−2 次移动距离更长,例如归纳中的 3-33−3、4-94−9、5-85−8 和 6-86−8。
第 22 种情况:对于每一次移动 ii,第 ii 次移动距离都比第 i-2i−2 次移动距离更短,即归纳中的 3-13−1 具有的性质。
第 33 种情况:对于每一次移动 i < ji<j,都满足第 11 种情况;对于每一次移动 i > ji>j,都满足第 22 种情况。
具体地,对于第 33 种情况的第 jj 次移动,有以下三种情况:
第 3.13.1 种情况:第 jj 次移动距离小于第 j-2j−2 次移动距离减去第 j-4j−4 次移动距离的差,例如归纳中的 5-15−1、5-45−4、6-46−4 等。此时,第 j+1j+1 次移动距离需要小于第 j-1j−1 次移动距离才能不出现路径交叉。在边界条件下,这种情况会变为:第 33 次移动距离小于第 11 次移动距离,即归纳中的 3-13−1;第 44 次移动距离小于第 22 次移动距离,即归纳中的 4-14−1、4-44−4 和 4-74−7。
第 3.23.2 种情况:第 jj 次移动距离大于等于第 j-2j−2 次移动距离减去第 j-4j−4 次移动距离的差,且小于等于第 j-2j−2 次移动距离,例如归纳中的 5-55−5、5-65−6、5-75−7 等。此时,第 j+1j+1 次移动距离需要小于第 j-1j−1 次移动距离减去第 j-3j−3 次移动距离的差,才能不出现路径交叉。在边界条件下,这种情况会变为:第 44 次的移动距离等于第 22 次的移动距离且第 33 次的移动距离大于第 11 次的移动距离,即归纳中的 4-84−8。
class Solution {
public boolean isSelfCrossing(int[] distance) {
int n = distance.length;
// 处理第 1 种情况
int i = 0;
while (i < n && (i < 2 || distance[i] > distance[i - 2])) {
++i;
}
if (i == n) {
return false;
}
// 处理第 j 次移动的情况
if ((i == 3 && distance[i] == distance[i - 2])
|| (i >= 4 && distance[i] >= distance[i - 2] - distance[i - 4])) {
distance[i - 1] -= distance[i - 3];
}
++i;
// 处理第 2 种情况
while (i < n && distance[i] < distance[i - 2]) {
++i;
}
return i != n;
}
}