728x90
반응형
https://www.lintcode.com/problem/787/
BFS 기본
- 방향 설정 & 배열 사이즈 변수 설정
- 맞는 조건 탐색
- 큐 생성
- 조건 체크해서 큐 넣기
- 마이너스 좌표 체크
- m*n 범위 체크
- grid[x][y]값 체크
문제 조건
1. 구슬은 벽이 없으면 한 방향으로 쭉 이동한다.
2. 이동한 다음에는 다른 방향으로 이동 가능하다.
3. 시작지점에서 목적지점까지 갈 수 있는지 여부 리턴
문제 풀이 순서 - BFS
1. Queue에서 poll 한후
2. 4방향으로 체크시작
3. 공식: 조건체크 부분 수행
4. (3,4)까지 도착한후 에러 체크 한다.
While문에 서 올린 좌표를 –로 원상복귀 visited[x][y]==true인지 체크 후 방문한적이 없으면 true 입력
5. queue.offer(2,4)
문제 풀이 순서 - DFS
1. Stack에 (0,4) push
2. 4방향으로 체크시작
3. 공식: 조건체크 부분 수행
4. (3,4)까지 도착한후 에러 체크 한다.
While문에 서 올린 좌표를 –로 원상복귀 visited[x][y]==true인지 체크 후 방문한적이 없으면 true 입력
5. DFS(2,4)
1. BFS 이용
class Point{
public int x, y;
Point(int x, int y){
this.x=x;
this.y=y;
}
}
public class Solution {
static int n,m;
static boolean[][]check;
public boolean hasPath(int[][] maze, int[] startpoint, int[] destination) {
//1.ds
Point start = new Point(startpoint[0], startpoint[1]);
Point dest = new Point(destination[0], destination[1]);
Queue<Point> q = new LinkedList<>();
n=maze.length;
m=maze[0].length;
int[][] dis = {{0,1},{1,0},{-1,0},{0,-1}};
check= new boolean[n][m];
q.offer(start);
while(!q.isEmpty()){
Point point = q.poll();
for(int i=0;i<4;i++){
boolean flag=false;
Point np = new Point(point.x+dis[i][0], point.y+dis[i][1]);
if(BFS(np, maze)){
while(!flag){
np=new Point(np.x+dis[i][0], np.y+dis[i][1]);
if(!BFS(np, maze)) flag=true;
}
np=new Point(np.x-dis[i][0], np.y-dis[i][1]);
//isValid 메서드 사용하지 않는 이유 : check에 true처리하면 안되므로
if(np.x==dest.x&&np.y==dest.y) return true;
if(check[np.x][np.y]==false){
q.offer(np);
//벽에 부딪혔을 때, check에 true 처리
check[np.x][np.y]=true;
}
}
}
}
return false;
}
public boolean BFS(Point point, int[][] maze){
if(!isValid(point)|| maze[point.x][point.y]!=0){
return false;
}
return true;
}
public boolean isValid(Point point){
if(point.x<0 || point.y<0 || point.x>=n||point.y>=m) return false;
return true;
}
}
+) 세련된 풀이
public class Solution {
static int[][] dis= {{-1,0},{1,0},{0,1},{0,-1}};
static int n,m;
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
n=maze.length;
m=maze[0].length;
//에러 체크
if(start[0]==destination[0] && start[1]==destination[1]) return true;
boolean[][] visited =new boolean[n][m];
//출발지점 세팅
visited[start[0]][start[1]]=true;
//1.ds
Queue<int[]> q = new LinkedList<>();
q.offer(start);
//큐가 빌때까지 반복
while(!q.isEmpty()){
int[] point= q.poll();
//0,4
for(int[] add : dis){
int x = point[0]+add[0];
int y = point[1]+add[1];
//구슬이 벽면까지 가는 반복문
while(x>=0 && y>=0 && x<n && y<m && maze[x][y]==0){
x+=add[0];
y+=add[1];
}
//구슬이 벽면에 도달시 -1해서 좌표 변수 설정
x-=add[0];
y-=add[1];
//구슬이 벽에 도달 시
//1. 방문 여부 확인
//2. 방문 했다고 체크
//3. 도착지점인지 확인
//4. 큐에 삽입
if(visited[x][y]) continue;
visited[x][y]=true;
if(x==destination[0] && y==destination[1]) return true;
q.offer(new int[]{x,y});
}
}
return false;
}
}
2. DFS 이용
class Point{
public int x, y;
Point(int x, int y){
this.x=x;
this.y=y;
}
}
public class Solution {
static int n,m;
static boolean[][]check;
static boolean answer=false;
static int[][] dis = {{0,1},{1,0},{-1,0},{0,-1}};
public boolean hasPath(int[][] maze, int[] startpoint, int[] destination) {
//1.ds
Point start = new Point(startpoint[0], startpoint[1]);
Point dest = new Point(destination[0], destination[1]);
n=maze.length;
m=maze[0].length;
check= new boolean[n][m];
return DFS(start, dest, maze);
}
public boolean DFS(Point point, Point dest,int[][] maze){
if(dest.x==point.x&&dest.y==point.y){
return true;
}
if(!isValid(point, maze)){
return false;
}
check[point.x][point.y]=true;
for(int i=0;i<4;i++){
boolean flag=false;
Point np=point;
while(!flag){
System.out.println(i);
np=new Point(np.x+dis[i][0], np.y+dis[i][1]);
if(np.x<0 || np.y<0 || np.x>=n||np.y>=m||maze[np.x][np.y]!=0) flag=true;
}
np=new Point(np.x-dis[i][0], np.y-dis[i][1]);
if(DFS(np, dest, maze)) return true;
}
return false;
}
public boolean isValid(Point point,int[][] maze){
if(point.x<0 || point.y<0 || point.x>=n||point.y>=m||maze[point.x][point.y]!=0 ||check[point.x][point.y]==true) return false;
return true;
}
}
+) 세련된 풀이
public class Solution {
static int[][] dis= {{-1,0},{1,0},{0,1},{0,-1}};
static int n,m;
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
n=maze.length;
m=maze[0].length;
//에러 체크
if(start[0]==destination[0] && start[1]==destination[1]) return true;
boolean[][] visited =new boolean[n][m];
//출발지점 세팅
visited[start[0]][start[1]]=true;
//DFS 호출
return DFS(maze, start, destination, visited);
}
public boolean DFS(int[][] maze, int[] start, int[] destination, boolean[][] visited){
//DFS의 경우 초기값부터 확인을 시작한다.
//1. 방문 여부 확인
//2. 방문했다고 체크
//3. 도착지점인지 확인
if(!isValid(start,maze)&& visited[start[0]][start[1]]==true){
return false;
}
visited[start[0]][start[1]]=true;
if(start[0]==destination[0]&& start[1]==destination[1]) return true;
for(int[] add : dis){
int x=start[0]+add[0];
int y=start[1]+add[1];
while(isValid(new int[]{x,y}, maze)){
x+=add[0];
y+=add[1];
}
x-=add[0];
y-=add[1];
System.out.println(start[0]+" "+start[1]+" "+x+" "+y);
//구슬이 벽에 도달 시
//1. 방문 여부 확인
//2. 스택에 삽입
if(visited[x][y]==true) continue;
if(DFS(maze, new int[]{x,y}, destination, visited)) return true;
}
return false;
}
public boolean isValid(int[] point, int[][] maze){
if(point[0]<0|| point[1]<0 || point[0]>=n || point[1]>=m || maze[point[0]][point[1]]==1){
return false;
}
return true;
}
}
728x90
반응형
'Java > Java 알고리즘 LeetCode' 카테고리의 다른 글
[LeetCode- Ch8. 동적계획법] 2. 계단 오르기 # (0) | 2022.11.02 |
---|---|
[LeetCode- Ch8. 동적계획법] 1. 유일한 경로 (0) | 2022.11.02 |
[LeetCode- Ch7. DFS & BFS] 6. 유효하지 않은 괄호 제거 (0) | 2022.11.01 |
[LeetCode- Ch7. DFS & BFS] 5. 단어 검색 # (0) | 2022.11.01 |
[LeetCode- Ch7. DFS & BFS] 4. 단어 사다리 # (0) | 2022.10.31 |