问题:
难度:Hard
说明:
给一个int[] arr,然后按顺序,上,左,下,右沿着直线行走 arr[i] 长度的路径距离,如果发现行走距离相交了,就返回true。
问题链接:https://leetcode.com/problems/self-crossing
输入案例:
Example 1:
┌───┐
│ │
└───┼──>
│
Input: [2,1,1,2]
Output: true
Example 2:
┌──────┐
│ │
│
│
└────────────>
Input: [1,2,3,4]
Output: false
Example 3:
┌───┐
│ │
└───┼>
Input: [1,1,1,1]
Output: true
我的代码:
使用visited表,记录已经访问的位置,然后就坐标轴处理就行了,代码比较难看点。
/**
* 注意坐标轴规定
* X2 (-)
* |
* |
* Y2(-) - - O - -> Y1 (+)
* |
* |
* X1 (+)
*/
class Solution {
public boolean isSelfCrossing(int[] x) {
int len = x.length;
// 第一象限
int X1 = 0;
int Y1 = 0;
// 第四象限
int X2 = 0;
int Y2 = 0;
for(int i = len;i -- > 0;)
if(i % 2 == 0 && i % 4 != 0) X2 = Math.max(x[i],X2);
else if(i % 2 == 0) X1 = Math.max(x[i],X1);
else if((i - 1) % 4 != 0) Y1 = Math.max(x[i],Y1);
else Y2 = Math.max(x[i],Y2);
// 原点
int X = X1;
int Y = Y2;
boolean[][] visited = new boolean[X1 + X2 + 1][Y1 + Y2 + 1];
visited[X][Y] = true;
// visited 表发现标记是 true ,就相交,否则标记为 true
for(int i = 0;i < len;i ++) {
if(i % 2 == 0 && i % 4 != 0) {
for(int j = X + 1;j <= X + x[i];j ++) {
if(visited[j][Y]) return true;
else visited[j][Y] = true;
}
X += x[i];
}
else if(i % 2 == 0) {
for(int j = X;j -- > X - x[i];) {
if(visited[j][Y]) return true;
else visited[j][Y] = true;
}
X -= x[i];
}
else if((i - 1) % 4 != 0) {
for(int j = Y + 1;j <= Y + x[i];j ++) {
if(visited[X][j]) return true;
else visited[X][j] = true;
}
Y += x[i];
}
else {
for(int j = Y;j -- > Y - x[i];) {
if(visited[X][j]) return true;
else visited[X][j] = true;
}
Y -= x[i];
}
}
return false;
}
}
其它代码:
没看,具体应该是数学公式处理出来。
class Solution {
public boolean isSelfCrossing(int[] x) {
for (int i = 3; i < x.length; ++i) {
if (x[i - 1] <= x[i - 3]) {
if (x[i] >= x[i - 2]) {
return true;
}
if (i > 3 &&
x[i - 1] == x[i - 3] &&
x[i] + x[i - 4] >= x[i - 2]) {
return true;
}
if (i > 4 &&
x[i - 1] + x[i - 5] >= x[i - 3] &&
x[i - 2] > x[i - 4] &&
x[i] + x[i - 4] >= x[i - 2]) {
return true;
}
}
}
return false;
}
}