[프로그래머스 알고리즘] 제일 작은 수 제거하기

Heejun Kwon·2021년 6월 9일
0

알고리즘 풀이

목록 보기
6/11
post-thumbnail

프로그래머스 연습문제
프로그래머스 - 제일 작은 수 제거하기



🔎 문제

정수를 저장한 배열, arr 에서 가장 작은 수를 제거한 배열을 리턴하는 함수, solution을 완성해주세요.

단, 리턴하려는 배열이 빈 배열인 경우엔 배열에 -1을 채워 리턴하세요.

예를들어 arr이 [4,3,2,1]인 경우는 [4,3,2]를 리턴 하고, [10]면 [-1]을 리턴 합니다.

🚫 제한조건

arr은 길이 1 이상인 배열입니다.

인덱스 i, j에 대해 i ≠ j이면 arr[i] ≠ arr[j] 입니다.

💻 입출력 예

📄🤔 코드 및 풀이과정

🔹 1번

public static int[] solution(int[] arr) {
	int len = arr.length;
	if(len==1) return new int[] {-1};

	int min = arr[0];
	for (int i = 1; i < len; i++) {	//가장 작은 수 구하기
		if(min > arr[i]) {
			min = arr[i];
		}
	}
		
	int count = 0;
	for (int i = 0; i < len; i++) {	//가장 작은 수의 개수 구하기
		if(min==arr[i]) {
			count++;
		}
	}
		
	int[] answer = new int[len-count];
	for (int i = 0, k = 0; i < len; i++) {	//가장 작은 수들을 제외한 배열 만들기
		if(arr[i] != min) {
			answer[k++] = arr[i];
		}
	}
    	return answer;
 }

🔸 1번 풀이

처음 코드는 크게 3단계로 나눠

  1. 가장 작은 수 구하기
  2. 가장 작은 수의 갯수 구하기
    (가장 작은 수는 여러개일 수 있기 때문)
  3. 가장 작은 수들을 제외한 배열 만들기

순서대로 로직을 구현하여 작성하였다.

다 풀고 나서 보니 많은 사람들이
가장 작은 수의 갯수가 1개만일 때를 가정해 문제를 풀었다.

문제에서 입력된 수들이 중복되지 않는다는 이야기가 없었으니
1개로 가정해 풀어 통과하더라도 문제의 조건상으론
가장 작은 수가 여러개일 수 있다는 가정 하에
알고리즘을 작성해야 한다 생각한다.

성공적으로 통과는 했으나
컬렉션을 활용해서도 문제를 풀어보고 싶어
추가적으로 문제를 풀어보았다.



🔹 2번

public static int[] solution(int[] arr) {
	int[] answer = {-1};
	if(arr.length == 1) return answer;
	
	ArrayList<Integer> list = new ArrayList<>();
	for (int i = 0; i < arr.length; i++) {	// ArrayList에 옮겨담기
		list.add(arr[i]);
	}
	
	int minValue = Collections.min(list);	// 가장 작은 수 구하기
	
	while(list.indexOf(minValue) != -1) {	// 가장 작은 수들 제거하기
		list.remove(list.indexOf(minValue));
	}
	
	if(list.size() != 0) {	// 리스트가 비지 않았을 경우 배열에 옮기기
		answer = new int[list.size()];
        for (int i = 0; i < answer.length; i++) {
			answer[i] = list.get(i);
		}
	}
	
    return answer; 
}

🔸 2번 풀이

이번엔 컬렉션과 API 활용해보았다.

뭔가... 반성할 점이 많이 보이는 코딩이였다.

  1. 배열을 ArrayList에 옮겨담기
  2. Collections의 min 메서드로 가장 작은 수 구하기
  3. 가장 작은 수들을 리스트에서 제거하기
  4. 리스트가 비지 않았을 경우 배열에 옮기기

순서대로 로직을 구현하여 작성하였는데
그렇게 효율적이지 못한 것 같다.

우선 1번부터 애로사항이 생겼다.
int 배열을 바로 Arrays.asList() 메서드로 ArrayList로 옮길 수 있을 줄 알았는데 실패했다.

ArrayList는 int형의 래퍼클래스인 Integer형이라 서로 다른 형으로 자동형변환이 되지 않아 for문으로 값을 하나하나 옮겼다.

가장 작은 수를 구하는 것은 collections 클래스의 min 메서드를 활용해보았다.

알고만 있었지 활용해 본 것은 이번이 처음인데
확실히 메서드로 구현이 되어 있으니 편의성 면에선 좋은 것 같다.

가장 작은 수를 제거할 때는 while문과 indexOf를 활용해
가장 작은 수가 여러 개일 때를 가정하여 제거해줬다.

4번에선 처음 answer을 [-1] 로 생성해두어 리스트가 비었을 경우
그대로 반환하고, 비지 않았을 경우 리스트를 배열에 옮겨 반환한다.

문제는 성공적으로 통과했으나
처리시간은 케이스별로 차이가 있지만 대체로 1번 코드보다 느렸다.

아직 컬렉션을 제대로 활용하는 방법을 몰라서일까?
컬렉션과 컬렉션의 메서드를 사용함으로써 내가 필요한 것 외의
불필요한 동작들이 발생해서일까?

정답은 둘 다인 것 같다.



😳❕ 소감 & 느낀점

이번 문제 역시도 그렇게 난이도 있는 문제는 아니라 생각했지만
매번 알고리즘 문제를 풀면서 반성하게 되는 것 같다.

컬렉션에 대해서 한두 번 훑어본 정도로 쓸 줄 안다고
착각했던 것이 부끄럽다.

정말로 잘 알고 쓸 줄 알았다면 2번 코드를 구현하면서
좀 더 빠른 처리속도와 깔끔한 코딩이 가능하지 않았을까 한다.

자바를 한두달 정도 배우고,
현재 데이터베이스, 웹을 배우고 있는데

"이것들 예습, 복습 하기도 바쁜데 자바까지 보기는 힘들지 않을까?"

하면서 한동안 자바 공부를 소흘히 한 댓가를
알고리즘 풀이를 하며 톡톡히 치르는 것 같다.

아직도 자바에 대해서 모르는게 너무 많은 것 같다.

그러니 아무리 지금 배우는게 많다고 해서 나태해지지 말고
자는 시간을 좀 더 줄여서라도 알고리즘 풀이를 꾸준히 진행하며
미흡했던 부분들을 다시 한 번 보고,
알고 있다고 생각하는 부분들도 좀 더 깊게 파고들어 봐야겠다.

0개의 댓글