코딩테스트 Lv - 1 공원 산책

박상하·2024년 8월 6일
0

코딩테스트

목록 보기
33/37


첫 번째 시도

이중 while문을 사용해서 직관적으로 한 스텝마다를 반복해주면 되지 않을까 생각을 했다.

이 문제에서 포인트는

주어진 방향으로 이동할 때 공원을 벗어나는지
주어진 방향으로 이동 중 장애물을 만나는지

위 두 가지를 체크해보는 것이다.

function solution(park, routes) {
 let x, y;
for(let i = 0 ; i<park.length; i++){
    for(let j =0; j<park[0].length; j++){
        if(park[i][j]==="S"){
            x=i
            y=j
        }
    }
}

routes=routes.map((route)=>route.split(` `)) 

// 실제로 한칸씩 가보기
    
const maxX = park.length-1
const maxY = park[0].length-1
    
while(routes.length>0){
  let X = x
  let Y = y
  let [direction,distance]= routes[0]
  let pass = true
  while(distance>0){
  if(direction==="E"){
    Y=Y+1  
  } 
  else if(direction==="W"){
    Y=Y-1   
  }
  else if(direction==="S"){
    X=X+1   
  }
  else if(direction==="N"){
    X=X-1   
  }    
   distance=distance-1
  if(park[X][Y]==="X"||X>maxX||Y>maxY||X<0 || Y<0){
      pass=false
      break;
  } 
      
 }
  if(pass===true){
     x=X
     y=Y 
  }
  routes.shift()
}
return [x,y]   
} 

결과: 런타임오류

몇개의 케이스를 제외하고 런타임오류가 발생하였다.
아무래도 하나의 스텝마다 반복문을 돌리는게 시간이 오래 걸리는 거 같다.

그렇다면 먼저 스텝을 하나만큼 이동하는 게 아니라 최종 목적지를 계산하고 이 결과가 공원 밖인지
아니면 장애물이 있는지를 계산해야한다.

두 번째 시도

장애물 위치를 배열로 저장하고 출발지와 한 번의 명령으로 얻은 도착지의 위치를 통해
장애물 위치를 지나는지를 체크하는 방법으로 구현을 했다.

출발지점-도착지점 -> 중간에 장애물이 있는지 체크 + 공원 범위 내인지

function solution(park, routes) {
 let x,y;
 let hurdle=[]   
 for(let i = 0 ; i<park.length; i++){
     for(let j = 0 ; j<park[0].length; j++){
        if(park[i][j]==="S"){
          x=i
          y=j  
        } 
        else if(park[i][j]==="X"){
         hurdle.push([i,j])   
        } 
     }
 }
    
    
routes=routes.map((route)=>route.split(` `))

const maxX = park.length-1
const maxY = park[0].length-1
    
for(let i = 0 ; i<routes.length; i++){
   let X=x
   let Y=y
  const [direction,distance]=routes[i] 
   
   if(direction==="E"){
     Y=Y+distance*1  
   }
   else if(direction==="W"){
     Y=Y-distance*1    
   }
   else if(direction==="S"){
     X=X+distance*1  
   }
   else if(direction==="N"){
     X=X-distance*1  
   } 
    
    if(X>maxX||Y>maxY||X<0||Y<0){
        continue;
    }
    
    let pass = true;
    
  for(let j = 0 ; j < hurdle.length; j++){
      const [hX,hY]=hurdle[j]
      if(hX===X){
         if((hY<=y&&hY>=Y) ||(hY>=y&&hY<=Y)){
             pass=false
             break;
         } 
      }
      else if(hY===Y){
          if((hX<=x&&hX>=X) ||(hX>=x&&hX<=X)){
             pass=false
             break;
         } 
      }   
  }
    if(pass===true){
        x=X
        y=Y
    }

}    
    return [x,y]
    
}

결과: 통과

이렇게 비교를 하는게 런타임 오류가 나지 않았다.

그런데 7개월전에 해당 문제를 풀었을 때 나의 풀이를 보니

1번의 방법으로 풀었는데도 런타임 오류가 나지 않았다.

그 이유를 알아보니 1번의 방법에서 while문을 넣고 Shift를 굳이 넣지 않아도

for문으로 충분히 커버가 가능했다. 즉, shift를 하는 과정에서 런타임 오류가 난 거같다.

shift는 배열의 맨 앞 요소를 제거한 후 재배치되어 많은 자원을 사용하게 되니 지양하자

0개의 댓글