본문 바로가기

ALGORITHM

[프로그래머스 Java] 같은 숫자는 싫어

 

코딩테스트 연습 - 같은 숫자는 싫어

배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은

programmers.co.kr

 

⏱소요 시간 - 정확성 20분 / 효율성 40분 = 1시간

 

🔑해결 방법

 

처음으로 효율성까지 검사하는 문제였다.

처음 아니랄까봐 효율성에서 모두 실패를 해서 질문하기에서 힌트를 얻어 문제를 다시 풀었다.

 

첫 번째 제출한 코드는

1. arr[]에 있는 값들을 모두 list에 넣는다.

2. list의 기준 값과 바로 다음 값을 비교하면서 같으면 list에서 기준 값을 삭제한다. 그리고 for문을 다시 처음부터 반복한다.

3. for문이 마무리되면, list를 answer[] 배열로 변환해준다.

 

두 번째 제출한 코드는

1. 빈 list를 생성한 후, 비교를 위해 arr[] 배열의 첫 번째 값(arr[0])만 넣어준다.

2. arr[]을 돌면서, 분기를 확인하여 list에 값을 추가한다.

3. for문이 마무리되면, list를 answer[] 배열로 변환해준다.

 

첫 번째 코드와 두 번째 코드의 다른 점은

첫 번째 코드는 배열을 리스트에 넣고 중복되는 수를 제거하는 방식

두 번째 코드는 배열에서 해당하는 값만 리스트에 추가하는 방식

 

즉, 여기서 알 수 있는 것은 코드의 효율성을 좋게 하려면 제거보다는 추가를 선택하는 것이 좋다!

 

 

🔎첫 번째 소스 코드

 

package step1;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

// 같은 숫자는 싫어
// 배열을 리스트에 넣고 중복되는 수를 제거하는 방식 (제거)
public class Ex10 {

	public static void main(String[] args) {
		
		System.out.println(solution(new int[]{ 1,1,3,3,0,1,1 }));
		System.out.println(solution(new int[]{ 4,4,4,3,3 }));
		
	}
	
	public static int[] solution(int[] arr) {
		
		int[] answer = {};
		
		List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
		
		for(int i = 0; i < list.size() - 1; i++) {
			
			if(list.get(i) == list.get(i+1)) {
				
				list.remove(i);
				i = -1; // 제거하면 순서가 변경되므로 다시 처음부터 돌기 위해 추가
	
			}
	
		}
		
		answer = list.stream().mapToInt(i->i).toArray();
		
		return answer;
	
	}

}

 

 

🔎효율성을 개선한 두 번째 소스 코드

 

package step1;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// 같은 숫자는 싫어
// 배열에서 해당하는 값만 리스트에 추가하는 방식 (추가)
public class Ex10_1 {

	public static void main(String[] args) {
		
		System.out.println(solution(new int[]{ 1,1,3,3,0,1,1 }));
		System.out.println(solution(new int[]{ 4,4,4,3,3 }));
		System.out.println(solution(new int[]{ 8,4,3,3,8,8,8 }));
		
	}
	
	public static int[] solution(int[] arr) {
		
		int[] answer = {};
		
		List<Integer> list = new ArrayList<>(); // 숫자를 추가할 리스트
		
		list.add(arr[0]); // 리스트의 첫 번째에는 비교를 위해 값을 먼저 넣어줌

		for(int i = 0; i < arr.length - 1; i++) {
			
			if(arr[i] == arr[i+1]) { // 기준 값과 다음 값이 같은데
				
				if(list.contains(arr[i])) { // 이미 리스트에 값이 포함되어 있다면
					continue; // 그냥 진행해 (이게 되는 이유, 아래 로직 때문에 문제되지 않음)
				} 
				
				list.add(arr[i]); // 기준 값만 추가해줘
				
			} 

			list.add(arr[i+1]); // 기준 값과 다음 값이 다를 경우 그냥 추가해줘

		}
		
		answer = list.stream().mapToInt(i->i).toArray();
		
		return answer;
	
	}

}

 

 

🔎다른 사람의 코드

 

내가 짠 코드처럼 복잡하게 나누어 분기하지 않아도

기준 값과 다음 값이 다를 때 그냥 다음 값만 추가해줘도 같은 결과를 얻을 수 있다 ^_________^

 

package step1;

import java.util.ArrayList;
import java.util.List;

// 같은 숫자는 싫어
// 배열에서 해당하는 값만 리스트에 추가하는 방식 (추가)
public class Ex10_2 {

	public static void main(String[] args) {
		
		System.out.println(solution(new int[]{ 1,1,3,3,0,1,1 }));
		System.out.println(solution(new int[]{ 4,4,4,3,3 }));
		System.out.println(solution(new int[]{ 8,4,3,3,8,8,8 }));
		
	}
	
	public static int[] solution(int[] arr) {
		
		List<Integer> list = new ArrayList<>(); // 숫자를 추가할 리스트
		
		list.add(arr[0]); // 리스트의 첫 번째에는 비교를 위해 값을 먼저 넣어줌

		for(int i = 0; i < arr.length - 1; i++) {
			
			if(arr[i] != arr[i+1]) {
				list.add(arr[i+1]); // 기준 값과 다음 값이 다를 경우 그냥 추가해줘
			}
			
		}
		
		// list -> Array 변환
		int[] answer = new int[list.size()];
		
		for(int i = 0; i < list.size(); i++) {
			answer[i] = list.get(i);
		}
		
		return answer;
	
	}

}