본문 바로가기

기록/알고리즘

[프로그래머스][그리디] 체육복

SMALL

 

programmers.co.kr/learn/courses/30/lessons/42862

 

코딩테스트 연습 - 체육복

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번

programmers.co.kr

 


문제 풀이

1. lost배열에 있는 학생은 -1로, reserve가 있는 학생은 ++를 해주어 2차원 배열을 생성한다.
   * 1, 또는 -1을 넣지 않고 ++과 --를 해주는 이유는 lostreserve에 같은 학생이 들어있을 경우 고려하기

2. lost를 최소화하기 위해 lost의 길이만큼 루프를 만들어 채울 수 있는지 확인한다.

3. lost를 채울 수 있다면 result[lost]++, result[lost - 1]++ or result[lost + 1]++로 상태를 업데이트한다.

4. result[i] >= 0인경우를 count하여 값을 return한다. (0인 경우는 자신의 것만, 이상인 경우 여분이 있는 경우)

 

코드

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int[][] result = new int[n][2];

		//reserve와 lost의 경우 배열에 반영
		for (int i = 0; i < reserve.length; i++) {
			result[reserve[i] - 1][1] ++;
		}
		for(int i = 0; i < lost.length; i++) {
			result[lost[i] - 1][1]--;
		}

		for (int i = 0; i < lost.length; i++) {
			// 맨앞, 뒤
			if (lost[i] - 1 == 0) {
				if (checkNext(lost, result, i)) {
					result[lost[i]][1]--;
					result[lost[i] - 1][1]++;
				}
			} else if (lost[i] - 1 == n - 1) {
				if (checkFront(lost, result, i)) {
					result[lost[i] - 2][1]--;
					result[lost[i] - 1][1]++;
				}

			} else { //그 외
                if (checkFront(lost, result, i) && result[lost[i] - 1][1] < 0) {
					result[lost[i] - 2][1]--;
					result[lost[i] - 1][1]++;
				}
				if (checkNext(lost, result, i) && result[lost[i] - 1][1] < 0) {
					result[lost[i]][1]--;
					result[lost[i] - 1][1]++;
				}
				
			}

		}
		int count = 0;
		for(int i = 0; i < result.length; i++) {
			if(result[i][1] >= 0) {
				count++;
			}
		}
		
		return count;
	}
    //내 위치 앞의 사람에게 여분이 있는지 검사
	public static boolean checkFront(int[] lost, int[][] result, int i) {
		if (result[lost[i] - 2][1] > 0) {
			return true;
		}
		return false;

	}
    //내 위치 뒤의 사람에게 여분이 있는지 검사
	public static boolean checkNext(int[] lost, int[][] result, int i) {
		if (result[lost[i]][1] > 0) {
			return true;
		}
		return false;
	}
}

다른 사람 코드를 구경하러 가서 몇가지 코드를 간략화할 수 있는 방법을 알게 되었다.

1. 1차원 배열 활용하기

    이건 생각했었는데 적용을 못했다. 사실상 비교하는부분이 i (index)파트이기 때문에 2차원 배열을 쓸 필요가 없다.

2. for - each 형태의 루프 사용하기

    for - each형태 루프를 아무리 사용해도 익숙해지지가 않는다... 더 많이 써보고 익숙해지는 수 밖에 없다. 

3. 배열 크기

    맨 앞, 뒤를 비교할 필요가 없도록 배열 크기를 n + 2로 설정하는 방법이다. 이건 정말 생각못했다.. 

SMALL