같은 숫자는 싫어

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/12906

문제에 대한 내용

문제

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

예를 들면,

  • arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
  • arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다. 배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.

제한 조건

배열 arr의 크기 : 1,000,000 이하의 자연수 배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수

입출력 예

arr answer
[1,1,3,3,0,1,1] [1,3,0,1]
[4,4,4,3,3] [4,3]

접근 방식

  1. 전체 숫자가 중복되어도 상관 없다.
  2. 따라서 set이 아니라 이전 숫자와 겹치는지 여부만 판단
  • 겹치면 추가 X
  • 겹치지지 않으면 추가 O
  1. 결과 return

결과

소스 코드

import java.util.*;

public class Solution {
    public int[] solution(int []arr) {

        List<Integer> list = new ArrayList<>();

        int tmp = -1;
        for (int a:arr){
            if (tmp != a) list.add(a);
            tmp = a;
        }
        return list.stream().mapToInt(i->i).toArray();
    }
}

결과 이미지

alt text

다른 접근 방식

다른 사람들의 소스 코드를 살펴 보니, 대부분 비슷한 방식으로 풀었다.
그 중에서 다른 방식은

  1. return 타입을 변경해서, 변환하지 않고 return
  2. String 타입으로 변환해서, split으로 사이즈를 구해서 int 배열의 크기를 구해서 int 배열에 값을 집어넣기

이 중에서 2번의 경우는 내가 생각해보지 못했던 방법이라서 자세히 알아봤다.

코드

import java.util.*;

public class Solution {
    public int[] solution(int []arr) {
        StringBuilder sb = new StringBuilder();
        int size = arr.length;
        sb.append(arr[0]);
        for(int i=1; i<size; i++){
            if(arr[i-1]!=arr[i]) sb.append(arr[i]);
        }
        String[] array = sb.toString().split("");
        size = array.length;
        int[] answer = new int[size];
        for(int i=0; i<size; i++){
            answer[i] = Integer.parseInt(array[i]);
        }
        return answer;
    }
}

코드를 라인별로 분석해보면,

  1. StringBuilder 객체 생성 및 초기화
  2. StringBuilder에 객체의 0번 인덱스 넣기
  3. for문을 돌면서 이전 인덱스와 비교해서 다른 경우에만 StringBuilder에 넣기
  4. split을 통해 배열로 변경
  5. 배열의 크기를 구해서 return 할 새로운 배열 생성
  6. for문을 통해 새로운 배열과 String 배열의 값을 인덱스 별로 일치시키기

알게 된 점

일반적으로 크기를 유연하게 관리하기 위해서는 리스트를 사용한다.
하지만, String으로 전환하면서 크기를 구하고 배열로 리턴할 수 있다는 사실이 접근이 새로운 것 같다.

그리고 사실, Java의 Stream API는 편의 + 간결성에 장점이 있는 것이기 때문에, 배열 혹은 리스트에서 값을 꺼내 새로운 배열로 리턴하는 것이 훨씬 효율적이다.