728x90

문제: https://school.programmers.co.kr/learn/courses/30/lessons/120844

 


1️⃣ 첫 번째 코드 (리스트 변환 사용)

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

class Solution {
    public int[] solution(int[] numbers, String direction) {
        List<Integer> list = Arrays.stream(numbers).boxed().collect(Collectors.toList());

        if (direction.equals("right")) {
            list.add(0, list.get(list.size() - 1)); // 마지막 원소를 맨 앞에 삽입
            list.remove(list.size() - 1); // 마지막 원소 제거
        } else {
            list.add(list.size(), list.get(0)); // 첫 번째 원소를 맨 뒤에 삽입
            list.remove(0); // 첫 번째 원소 제거
        }
        return list.stream().mapToInt(Integer::intValue).toArray();
    }
}

🔹 특징

  1. 배열을 List<Integer>로 변환한 후, 리스트 연산을 통해 이동을 수행.
  2. add(0, element) 또는 add(size, element)를 사용해 요소를 앞뒤로 이동.
  3. 마지막에 stream()을 사용하여 다시 int[]로 변환.

🟢 장점

  • 코드가 직관적이며 리스트의 메서드를 활용하여 쉽게 이해할 수 있음.

🔴 단점

  • 성능이 비효율적
    • Arrays.stream(numbers).boxed().collect(Collectors.toList()) → O(N)
    • add(index, element)와 remove(index) → O(N)
    • 최종적으로 list.stream().mapToInt(Integer::intValue).toArray() → O(N)
    • 전체 시간 복잡도: O(N) + O(N) + O(N) = O(N)
  • 불필요한 오토박싱 & 언박싱 발생
    • int를 Integer로 변환(boxing), 다시 int로 변환(unboxing) → 성능 저하 가능성 있음.

2️⃣ 두 번째 코드 (배열 인덱스 이동 사용)

class Solution {
    public int[] solution(int[] numbers, String direction) {
        int len = numbers.length;
        int[] answer = new int[len];
        boolean rightMove = "right".equals(direction);
        
        for (int i = 0; i < len; i++) {
            answer[rightMove ? (i + 1) % len : (i - 1 + len) % len] = numbers[i];
        }
        return answer;
    }
}

🔹 특징

  1. 새로운 배열 answer을 생성하고 수학적 연산을 이용해 인덱스를 조정하여 값을 삽입.
  2. 오른쪽 이동(right) → answer[(i + 1) % len] = numbers[i];
  3. 왼쪽 이동(left) → answer[(i - 1 + len) % len] = numbers[i];

🟢 장점

  • 성능이 매우 우수함 (O(N))
    • 단순 반복문과 인덱스 연산만 사용하여 추가적인 리스트 변환 없이 처리.
    • 리스트 변환, 박싱/언박싱이 없어 불필요한 성능 손실 없음.
  • 메모리 사용량이 적음
    • int[]만 사용하므로 추가적인 객체 생성이 없음.

🔴 단점

  • answer[rightMove ? (i + 1) % len : (i - 1 + len) % len] = numbers[i];
    → 가독성이 살짝 떨어질 수 있음.
    → 하지만 수학적 연산이므로 이해하면 훨씬 효율적임.

🏆 최종 결론: 두 번째 코드가 더 좋음!

첫 번째 코드 (리스트 변환) 두 번째 코드 (배열 인덱스 연산)

시간 복잡도 O(N) + O(N) + O(N) = O(N) O(N)
메모리 사용 추가적으로 List<Integer> 사용 int[] 배열만 사용 (메모리 절약)
성능 리스트 변환과 박싱/언박싱으로 성능 저하 빠른 배열 인덱스 계산
가독성 직관적이지만 리스트 변환 과정이 필요 다소 수학적이지만 최적화됨
추천 여부 ❌ 비효율적 ✅ 최적

💡 결론:

두 번째 코드(배열 인덱스 연산 방식)더 빠르고 메모리 효율적이며 최적화됨.

728x90

+ Recent posts