프로그래머스 | LV.2 방문 길이 - HashMap과 객체 equals, hashCode 재정의 문풀 (Java)

728x90

⬛ 프로그래머스 | LV.2 방문 길이 - HashMap과 객체 equals, hashCode 재정의 문풀

https://school.programmers.co.kr/learn/courses/30/lessons/49994

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 설명1
문제 설명2
문제 설명 3


💚나의 풀이

풀이 설명

  • 기본적으로 dx와 dy를 정의하는 것도 U, D, L, R의 명령어에 맞게 제대로 정의해야 한다.
 U(위), D(아래), L(왼), R(오)

int dx = {0, 0, -1, 1};
int dy = {1, -1,  0, 0};

인덱스로 방향을 구분해주자. 
만약 현재 명령어가 'U' 가 나왔다면 dx, dy는 idx = 0의 값으로 수행해야 한다.
  • 특히 이 문제에서 주의해야 할 점이 있다. (몇시간동안 틀렸던 이유!!!)
  • (1, 1) → (2,2) 에 대한 경로와 (2, 2) → (1,1) 역방향으로 간 경로도 똑같은 경로로 쳐야 한다는 거다.
  • 내가 풀이한 매커니즘은 Point(curX, curY, nx, ny) 를 갖는 클래스를 하나 만드는데 이 안에서 equals()와 hashCode()를 재정의 하여 정방향과 역방향의 필드값이 모두 같은 Point 객체에 대해서 동일한 객체로 인식하도록 재정의하고, HashMap<Point, Integer>에서 중복되는 경로를 카운팅하도록 했다.
  • 그렇게 되면 map의 size()가 곧 정답이 되기 때문이다.
  • 좌표의 경계를 넘어가도 없는 무시해야 하는 것도 꼭 주의해야 한다.

→ 이 문제의 경우 (-5 ≤ nx ≤ 5 ) && (-5 ≤ny ≤5) 내부의 값이어야 하고, 경계를 벗어난 값에 대해서는 무시해야 한다. curX, curY도 업데이트 하면 안된다.


[ 참고 ] : [equals와 hashCode() 재정의와 관련된 글]

💡 기본적으로 객체는 생성할 때마다 다른 객체로 인식한다. 나는 클래스의 필드가 일치하는 객체에 대해서는 동일한 객체로 간주하고 싶었다. 그러려면 equals() 와 hashCode()를 필드 기준으로 동일 객체로 간주하도록 재정의해야 했기 때문에 관련 게시글을 열심히 뒤져보고 참고했다. 어쨋든 해결해서 너무 기쁘다.

💚 제출 코드

import java.util.*;

class Point{
    int curx, cury, nx, ny;
    Point(int curx, int cury, int nx, int ny){
        this.curx = curx;
        this.cury = cury;
        this.nx = nx;
        this.ny = ny;
    }
    
    @Override 
    public boolean equals(Object obj){
        if(obj instanceof Point){
            Point o = (Point) obj;
            //정방향과 역방향 모두를 비교해서 (1,1) -> (1,2) 이든 (1,2) -> (1,1 ) 이든 같은 경로로 인식할 수 있게 재정의했다.
            return (this.curx == o.curx && this.cury == o.cury && this.nx == o.nx && this.ny == o.ny) || (this.curx == o.nx && this.cury == o.ny && this.nx == o.curx && this.ny == o.cury);
        }
        return false;
    } 
    
    @Override
    public int hashCode(){
        // 이 경우도 마찬가지다.
        return Objects.hash(Math.min(curx, nx), Math.min(cury, ny), Math.max(curx, nx), Math.max(cury, ny));
    }
}
class Solution {
    static int[] dx = {0, 0, -1, 1};
    static int[] dy = {1, -1, 0, 0 };
    
    public int solution(String dirs) {
        int answer = 0;
        int curX = 0, curY = 0;
        
        Map<Point, Integer> map = new HashMap<>();
        
        for(char x : dirs.toCharArray()){
            int dirIdx = 0;
            
            if(x == 'U'){
                dirIdx = 0;
            }else if(x == 'D'){
                dirIdx = 1;
            }else if(x == 'L'){
                dirIdx = 2;
            }else if(x == 'R'){
                dirIdx = 3;
            }
            
            int nx = curX + dx[dirIdx];
            int ny = curY + dy[dirIdx];
            
            if(nx >= -5 && nx <= 5 && ny >= -5 && ny <= 5) {
                Point path = new Point(curX, curY, nx, ny);
                map.put(path, map.getOrDefault(path, 0) + 1);
                
                curX = nx;
                curY = ny;
            }
        }
        
        System.out.println(map.size());
        
        return map.size();
    }
}
728x90