[프로그래머스] 조이스틱

[1차 시도. 최소 값을 기준으로 순회]

	class Solution {
    private static int[] minArr;

    public int solution(String name) {
        int answer = 0;
        minArr = new int[name.length()];

        int index = 0;
        for (char alphabet : name.toCharArray()) {
            minArr[index++] = alphabet - 'A' < 'Z' -  alphabet + 1 ?
                    alphabet - 'A' : 'Z' - alphabet + 1;
        }

        int nowIndex = 0;

        while(isPlaying()) {
            if(minArr[nowIndex] != 0) {
                answer += minArr[nowIndex];
                minArr[nowIndex] = 0;
            }

            int prev = 1;
            int next = 1;
            int prevIndex;
            int nextIndex;

            if(!isPlaying()) {
                break;
            }

            while(true) {
                prevIndex = nowIndex - prev >= 0 ? nowIndex - prev : minArr.length - 1;
                if(minArr[prevIndex] != 0) {
                    break;
                }
                prev += 1;
            }

            while(true) {
                nextIndex = nowIndex + next < minArr.length ? nowIndex + next : 0;
                if(minArr[nextIndex] != 0) {
                    break;
                }
                next += 1;
            }
            nowIndex = prev < next ? prevIndex : nextIndex;
            answer += prev < next ? prev : next;
        }

        return answer;
    }

    private boolean isPlaying() {
        for (int number : minArr) {
            if(number != 0) {
                return true;
            }
        }
        return false;
	}
}
  1. 각 문자를 변환시키는 최소값을 구하는 배열을 선언한다.
  2. 현재 인덱스를 기준으로 좌측과 우측의 이동 수를 체크한다.
  3. 이동 횟수를 확인하고 최소 이동 수를 이동한다.
  4. 최소 이동 방향으로 현재 인덱스를 갱신한다.

[결과. 런타임 에러 발생]

  • 원인이 prevIndex와 nextIndex에서 발생하는 에러인거 같다.

[2차 시도. 좌우 순환 부분 수정]

class Solution {
    private static int[] minArr;

    public int solution(String name) {
        int answer = 0;
        minArr = new int[name.length()];

        int index = 0;
        for (char alphabet : name.toCharArray()) {
            minArr[index++] = Math.min(alphabet - 'A', 'Z' - alphabet + 1);
        }


        int nowIndex = 0;

        while (true) {
            answer += minArr[nowIndex];
            minArr[nowIndex] = 0;

            int prev = 1;
            int next = 1;
            int prevIndex;
            int nextIndex;

            if (!isPlaying()) {
                break;
            }

            while (true) {
                prevIndex = nowIndex - prev >= 0 ?
                        nowIndex - prev : (minArr.length + (nowIndex - prev) % minArr.length);
                if (minArr[prevIndex] != 0) {
                    break;
                }
                prev += 1;
            }

            while (true) {
                nextIndex = nowIndex + next < minArr.length ?
                        nowIndex + next : (nowIndex + next) % minArr.length;
                if (minArr[nextIndex] != 0) {
                    break;
                }
                next += 1;
            }
            nowIndex = prev < next ? prevIndex : nextIndex;
            answer += Math.min(prev, next);
        }
        return answer;
    }

    private boolean isPlaying() {
        for (int number : minArr) {
            if (number != 0) {
                return true;
            }
        }
        return false;
    }
}

[이전 코드와의 차이]

  1. 좌우를 탐색하는 코드에서 순환하는 방식으로 변경하였다.
  • 좌측으로 순환하는 구조
            while (true) {
                prevIndex = nowIndex - prev >= 0 ?
                        nowIndex - prev : (minArr.length + (nowIndex - prev) % minArr.length);
                if (minArr[prevIndex] != 0) {
                    break;
                }
                prev += 1;
            }
  • 우측으로 순환하는 구조
            while (true) {
                nextIndex = nowIndex + next < minArr.length ?
                        nowIndex + next : (nowIndex + next) % minArr.length;
                if (minArr[nextIndex] != 0) {
                    break;
                }
                next += 1;
            }

  • Good

  1. 문제의 럼타임 에러를 스스로 발견해서 문제를 해결했다.
  • Bad

  1. 이 문제 에러를 잡은 시간을 많이 소요함.

⭐️ 좀 더 학습해야 할 부분

  • 좌, 우 순환 구조에 대해서 다시 한번 확인해서 접근해보기
  • 좌측으로 순환하는 구조(prevIndex에 초점을 맞춰서)
            while (true) {
                prevIndex = nowIndex - prev >= 0 ?
                        nowIndex - prev : (minArr.length + (nowIndex - prev) % minArr.length);
                if (minArr[prevIndex] != 0) {
                    break;
                }
                prev += 1;
            }
  • 우측으로 순환하는 구조 (nextIndex부분 초점을 맞춰서)
            while (true) {
                nextIndex = nowIndex + next < minArr.length ?
                        nowIndex + next : (nowIndex + next) % minArr.length;
                if (minArr[nextIndex] != 0) {
                    break;
                }
                next += 1;
            }

좋은 웹페이지 즐겨찾기