본문 바로가기

코딩테스트

프로그래머스(JAVA) - STACK/QUEUE (같은 숫자는 싫어)

 

문제정리

배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하고, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 한다.
해당 남은 수들을 return

 

작성한 코드

class Solution {
    public int[] solution(int[] arr) {
        List<Integer> list = new ArrayList<>();
        list.add(arr[0]);

        for(int i = 1; i < arr.length; i++){
            if(arr[i-1] == arr[i]){
                continue;
            }else {
                list.add(arr[i]);
            }
        }

        int[] answer = new int[list.size()];

        for(int i = 0; i < list.size(); i++){
            answer[i] = list.get(i);
        }
        return answer;
    }
}

 

연속적으로 나타나는 숫자를 하나만 남기고 전부 제거해야 해야하는데 if(arr[i-1] == arr[i]) 이걸로 해결 하고, int[]에 해당 값을 넣어서 반환시켰는데 뭔가 저 반환하는 값을 다르게 표현할 수 있지 않을까?

일단 시간은..

 

다른 사람의 코드

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

public class Solution {
    public int[] solution(int[] arr) {
        List<Integer> list = new ArrayList<>();
        list.add(arr[0]);

        for (int i = 1; i < arr.length; i++) {
            if (arr[i - 1] == arr[i]) {
                 continue;
            } else { 
                 list.add(arr[i]);
            }
        }

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

 

list.stream().mapToInt(i -> i).toArray();
Stream을 활용하면 내부적으로 최적화되어 for문을 사용하는 것보다 코드가 더 간결하고 가독성이 좋아진다. 성능 차이는 거의 없음! 하지만 아주 큰 데이터에서는 for 문이 더 빠를 수도 있다!

근데.. Integer과 int의 차이는 뭐지... mapToInt(i -> i)로 Integer에서 int로 변환한다는 건데 왜..

Integer은 객체..! int는 기본형..! (이거 기본이잖아ㅠ 또....)
Integer은 객체이고, null값을 가질 수 있다. 참조형 데이터 타입이라 메모리에 객체로 저장되며 연산을 수행할 때 속도가 느릴 수 있음
int는 기본 자료형, 값 자체를 저장하고 있어서 연산 속도가 빠름

List<Integer>에서 int[] 배열로 변환하려면, 객체를 기본형으로 변환해야하기에..!!

 

스택으로 해결

import java.util.Stack;

public class Solution {
    public int[] solution(int[] arr) {
        // 스택 생성
        Stack<Integer> stack = new Stack<>();

        // arr 순회
        for (int i : arr) {
            // 스택이 비어있거나 i가 스택의 마지막 요소와 다르면 push
            if (stack.empty() || !stack.peek().equals(i)) {
                stack.push(i);
            }
        }

        // stack을 배열(int[])로 변환
        return stack.stream().mapToInt(i -> i).toArray();
    }
}

 

중복 제거 로직이 스택의 특성 (LIFO, Last-IN First-Out)을 활용하여 간결
peek() 로 바로 직전 요소를 확인할 수 있다. 맨 위 코드에서 arr[i-1]와 같은 의미