文章目录
题目描述
给你一个整数数组 distance 。
从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说,每次移动后你的方位会发生逆时针变化。
判断你所经过的路径是否相交。如果相交,返回 true ;否则,返回 false 。
提示:
1 <= distance.length <= 105
1 <= distance[i] <= 105
找出所有路径交叉的情况(归纳法)
当 i 小于等于3的时候,肯定不会交叉,故从 i 为4开始讨论:
1. 第一种交叉情况
if( (distance[i]>=distance[i-2]) && (distance[i-1]<=distance[i-3]) )
return true;
2. 第二种交叉情况
if( (i>=4) && (distance[i-1]==distance[i-3]) && (distance[i]+distance[i-4]>=distance[i-2]) )
return true;
3. 第三种交叉情况
if( (i>=5)
&& (distance[i]+distance[i-4]>=distance[i-2])
&& (distance[i-1]+distance[i-5]>=distance[i-3])
&& (distance[i-2]>distance[i-4])
&& (distance[i-3]>distance[i-1]))
return true;
4. 完整代码如下
public class Practice03_3 {
public boolean isSelfCrossing(int[] distance) {
int n = distance.length;
if(n < 4)
return false;
for(int i=3;i<n;i++){
if( (distance[i]>=distance[i-2]) && (distance[i-1]<=distance[i-3]) )
return true;
if( (i>=4) && (distance[i-1]==distance[i-3]) && (distance[i]+distance[i-4]>=distance[i-2]) )
return true;
if( (i>=5) &&
(distance[i]+distance[i-4]>=distance[i-2]) &&
(distance[i-1]+distance[i-5]>=distance[i-3]) &&
(distance[i-2]>distance[i-4]) &&
(distance[i-3]>distance[i-1]))
return true;
}
return false;
}
}
图的邻接矩阵存储路线(耗内存)
1.思路
建立一个二维数组,初始化为0,将路线的坐标与二维数组的横坐标和纵坐标联系起来,走过的位置记为1。
2.完整代码如下
public class Practice03 {
public boolean isSelfCrossing(int[] distance) {
int N = 1000;
int route[][] = new int[N][N];
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
route[i][j]=0;
int row = N/2-1, col = N/2-1;
route[row][col]=1;
for(int i = 0;i<distance.length;i++){
if((i+1)%4 == 1){ // 向上走,col+
int len = distance[i];
for(int j=0;j<len;j++){
col++;
if(route[row][col]==1)return true;
route[row][col]=1;
}
}else if((i+1)%4 == 2){ // 向左走,row-
int len = distance[i];
for(int j=0;j<len;j++){
row--;
if(route[row][col]==1)return true;
route[row][col]=1;
}
}else if((i+1)%4 == 3){ // 向下走,col-
int len = distance[i];
for(int j=0;j<len;j++){
col--;
if(route[row][col]==1)return true;
route[row][col]=1;
}
}else{ // 向右走,row+
int len = distance[i];
for(int j=0;j<len;j++){
row++;
if(route[row][col]==1)return true;
route[row][col]=1;
}
}
}
return false;
}
}
用集合存储坐标(耗时间)
1.完整代码如下
用一个集合把走过的坐标转为字符串存储起来,每走一步,就与集合中的元素匹配。
2.完整代码如下
import java.util.ArrayList;
import java.util.List;
public class Practice03_2 {
public boolean isSelfCrossing(int[] distance) {
int N = 200000;
List<String> route=new ArrayList<String>();
int row = N/2-1, col = N/2-1;
String r_c = row+""+col;
route.add(r_c);
for(int i = 0;i<distance.length;i++){
if((i+1)%4 == 1){ // 向上走,col+
int len = distance[i];
for(int j=0;j<len;j++){
col++;
String temp = row+""+col;
if(exist(route,temp))return true;
route.add(temp);
}
}else if((i+1)%4 == 2){ // 向左走,row-
int len = distance[i];
for(int j=0;j<len;j++){
row--;
String temp = row+""+col;
if(exist(route,temp))return true;
route.add(temp);
}
}else if((i+1)%4 == 3){ // 向下走,col-
int len = distance[i];
for(int j=0;j<len;j++){
col--;
String temp = row+""+col;
if(exist(route,temp))return true;
route.add(temp);
}
}else{ // 向右走,row+
int len = distance[i];
for(int j=0;j<len;j++){
row++;
String temp = row+""+col;
if(exist(route,temp))return true;
route.add(temp);
}
}
}
return false;
}
public boolean exist(List<String> list,String s){
for(String str:list){
if(s.equals(str))return true;
}
return false;
}
}
总结
第一种方法时空复杂度最好。
其余的下次更吧~~~