[프로그래머스] 뒤에서 5등까지

2024. 10. 12. 22:20·여러가지/알고리즘 & 자료구조

뒤에서 5등까지 - 알고리즘 문제 풀이 (Java & Python)

이번 글에서는 정수로 이루어진 리스트 num_list에서 가장 작은 5개의 수를 오름차순으로 반환하는 문제를 풀어보겠습니다. Java와 Python으로 문제를 해결해보고, 각각의 풀이 방법에 대한 시간 및 공간 복잡도를 분석한 후, 다양한 Java 풀이 방법과 그에 대한 비교를 설명드리겠습니다.

문제 설명

정수로 이루어진 리스트 num_list가 주어집니다. 이 리스트에서 가장 작은 5개의 수를 오름차순으로 담은 리스트를 반환하는 solution 함수를 구현하세요.

제한사항

  • 6 ≤ num_list의 길이 ≤ 30
  • 1 ≤ num_list의 원소 ≤ 100

입출력 예

num_list 결과
[12, 4, 15, 46, 38, 1, 14] [1, 4, 12, 14, 15]

입출력 예 #1: [12, 4, 15, 46, 38, 1, 14]를 정렬하면 [1, 4, 12, 14, 15, 38, 46]이 되고, 앞에서부터 5개를 고르면 [1, 4, 12, 14, 15]가 됩니다.

해결 방법

이 문제를 해결하기 위해 리스트를 정렬한 후 가장 작은 5개의 수를 추출합니다. 각각의 언어(Java, Python)로 코드와 설명을 제공하며, 시간 및 공간 복잡도를 분석하겠습니다.

Python 코드

def solution(num_list):
    # 리스트를 오름차순으로 정렬하고, 가장 작은 5개의 수를 반환
    return sorted(num_list)[:5]
시간 및 공간 복잡도
  • 시간 복잡도: O(n log n) - 리스트를 정렬하는 데 걸리는 시간입니다. 여기서 n은 num_list의 길이입니다.
  • 공간 복잡도: O(n) - 정렬 과정에서 추가적인 공간이 필요하며, 결과 리스트를 저장하기 위한 공간도 필요합니다.

Java 코드

import java.util.Arrays;

class Solution {
    public int[] solution(int[] num_list) {
        // 배열을 오름차순으로 정렬
        Arrays.sort(num_list);

        // 가장 작은 5개의 원소를 반환
        return Arrays.copyOfRange(num_list, 0, 5);
    }
}
시간 및 공간 복잡도
  • 시간 복잡도: O(n log n) - 배열을 정렬하는 데 걸리는 시간입니다. 여기서 n은 num_list의 길이입니다.
  • 공간 복잡도: O(n) - 정렬 과정에서 추가적인 메모리가 사용되며, 결과 배열을 저장하기 위한 공간도 필요합니다.

다양한 Java 풀이 방법 소개

위의 기본 풀이 외에도 자바에서는 다양한 방법으로 이 문제를 해결할 수 있습니다. 몇 가지 추가적인 풀이 방법을 살펴보겠습니다.

1. 우선순위 큐(Priority Queue) 사용

Java의 PriorityQueue를 사용하여 가장 작은 5개의 수를 찾을 수 있습니다.

import java.util.PriorityQueue;
import java.util.Collections;

class Solution {
    public int[] solution(int[] num_list) {
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        for (int num : num_list) {
            minHeap.add(num);
        }

        int[] result = new int[5];
        for (int i = 0; i < 5; i++) {
            result[i] = minHeap.poll();
        }
        return result;
    }
}
설명
  • 우선순위 큐 사용: PriorityQueue는 기본적으로 최소 힙(min heap)으로 구현되어 있어, 원소를 추가할 때마다 자동으로 정렬됩니다.
  • 작은 값 추출: poll()을 사용하여 가장 작은 값들을 차례로 추출합니다.
장점 및 단점
  • 장점: 큰 배열에서 상위 몇 개의 원소를 추출할 때 유리합니다.
  • 단점: 전체 정렬보다 복잡한 방법이며, 추가적인 데이터 구조 사용으로 메모리 오버헤드가 발생할 수 있습니다.

2. Stream API 사용

Java 8 이상의 버전에서는 Stream API를 이용하여 간결하게 문제를 해결할 수 있습니다.

import java.util.Arrays;
import java.util.stream.IntStream;

class Solution {
    public int[] solution(int[] num_list) {
        return IntStream.of(num_list)
                        .sorted()
                        .limit(5)
                        .toArray();
    }
}
설명
  • Stream 사용: IntStream.of(num_list)를 통해 배열을 스트림으로 변환하고, sorted() 메서드를 이용해 정렬한 후, limit(5)로 상위 5개의 원소를 추출합니다.
  • 간결함: 코드가 간결하며 직관적입니다.
장점 및 단점
  • 장점: 코드가 간결하고, 함수형 스타일로 작성되어 가독성이 높습니다.
  • 단점: 작은 배열에서는 성능 차이가 없지만, 스트림 사용에 따른 약간의 성능 오버헤드가 발생할 수 있습니다.

비교 및 결론

  • 기본 Arrays.sort() 사용: 가장 직관적이며 간단한 방법으로, 배열의 크기가 작을 때 유리합니다.
  • 우선순위 큐 사용: 큰 데이터에서 상위 몇 개의 원소를 빠르게 추출할 때 유리하지만, 작은 배열에서는 불필요한 오버헤드가 발생할 수 있습니다.
  • Stream API 사용: 함수형 프로그래밍 스타일로 코드가 간결하며 가독성이 높지만, 내부적으로 반복자를 사용하므로 성능 오버헤드가 발생할 수 있습니다.

응용 문제

만약 오름차순이 아닌 내림차순으로 한다면?

Python 코드

def solution(num_list):
    # 리스트를 오름차순으로 정렬하고, 가장 작은 5개의 수를 추출한 뒤, 내림차순으로 정렬하여 반환
    return sorted(sorted(num_list)[:5], reverse=True)

Java 코드

import java.util.Arrays;
import java.util.Collections;

class Solution {
    public int[] solution(int[] num_list) {
        return Arrays.stream(num_list)
                     .boxed()  // int -> Integer로 변환
                     .sorted(Collections.reverseOrder())  // 내림차순 정렬
                     .limit(5)  // 상위 5개 추출
                     .mapToInt(Integer::intValue)  // Integer -> int로 변환
                     .toArray();  // int[] 배열로 변환

    }
}

1. 우선순위 큐(Priority Queue) 사용

Java의 PriorityQueue를 사용하여 가장 작은 5개의 수를 찾은 후, 내림차순으로 정렬할 수 있습니다.

import java.util.PriorityQueue;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;

class Solution {
    public List<Integer> solution(int[] num_list) {
        // 내림차순 우선순위 큐 (최대 힙)
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());

        // num_list 배열의 모든 요소를 큐에 삽입
        for (int num : num_list) {
            maxHeap.add(num);
        }

        // 큐에서 상위 5개의 값을 추출하여 배열로 변환
        int[] result = new int[5];
        for (int i = 0; i < 5; i++) {
            result[i] = maxHeap.poll();  // 큐에서 값을 꺼내서 배열에 저장
        }

        // 이미 큐에서 꺼낸 값들이 내림차순이므로 별도의 정렬은 필요 없음
        return result;
    }
}
설명
  • 우선순위 큐 사용: PriorityQueue는 기본적으로 최소 힙(min heap)으로 구현되어 있어, 원소를 추가할 때마다 자동으로 정렬됩니다.
  • 작은 값 추출: poll()을 사용하여 가장 작은 값들을 차례로 추출한 후, 결과를 내림차순으로 정렬합니다.
장점 및 단점
  • 장점: 큰 배열에서 상위 몇 개의 원소를 추출할 때 유리합니다.
  • 단점: 전체 정렬보다 복잡한 방법이며, 추가적인 데이터 구조 사용으로 메모리 오버헤드가 발생할 수 있습니다.

문제의 제한 조건(배열의 길이가 최대 30)에 비추어 볼 때, 각 방법의 성능 차이는 거의 없으며, 개인의 선호도와 코드 스타일에 따라 선택하면 됩니다. 간결한 코드를 원한다면 Stream API를, 명시적인 데이터 구조 활용을 원한다면 우선순위 큐를 사용하는 것이 좋습니다.

이 글을 통해 배열의 가장 작은 5개의 원소를 추출하는 문제를 다양한 방식으로 해결해 보았습니다. 여러분의 상황에 맞는 방법을 선택하여 효율적으로 문제를 해결해 보세요! 😊

저작자표시 (새창열림)

'여러가지 > 알고리즘 & 자료구조' 카테고리의 다른 글

[프로그래머스] 평균 구하기  (0) 2024.10.13
[프로그래머스] 나머지가 1이되는 수 찾기  (0) 2024.10.12
[프로그래머스] 원소들의 곱과 합  (0) 2024.10.12
[프로그래머스] 마지막 두 원소  (0) 2024.10.12
[프로그래머스] 수 조작하기1  (0) 2024.10.12
'여러가지/알고리즘 & 자료구조' 카테고리의 다른 글
  • [프로그래머스] 평균 구하기
  • [프로그래머스] 나머지가 1이되는 수 찾기
  • [프로그래머스] 원소들의 곱과 합
  • [프로그래머스] 마지막 두 원소
hyeseong-dev
hyeseong-dev
안녕하세요. 백엔드 개발자 이혜성입니다.
  • hyeseong-dev
    어제 오늘 그리고 내일
    hyeseong-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (282)
      • 여러가지 (107)
        • 알고리즘 & 자료구조 (72)
        • 오류 (4)
        • 이것저것 (29)
        • 일기 (1)
      • 프레임워크 (39)
        • 자바 스프링 (39)
        • React Native (0)
      • 프로그래밍 언어 (38)
        • 파이썬 (30)
        • 자바 (3)
        • 스프링부트 (5)
      • 운영체제 (0)
      • DB (17)
        • SQL (0)
        • Redis (17)
      • 클라우드 컴퓨팅 (2)
        • 도커 (2)
        • AWS (0)
      • 스케쥴 (65)
        • 세미나 (0)
        • 수료 (0)
        • 스터디 (24)
        • 시험 (41)
      • 트러블슈팅 (1)
      • 자격증 (0)
        • 정보처리기사 (0)
      • 재태크 (4)
        • 암호화폐 (4)
        • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    java
    프로그래머스
    Python
    완전탐색
    항해99
    AWS
    파이썬
    FastAPI
    ecs
    spring
    Spring Boot
    celery
    docker
    EC2
    Redis
    그리디
    mybatis
    RDS
    DP
    reactor
    #개발자포트폴리오 #개발자이력서 #개발자취업 #개발자취준 #코딩테스트 #항해99 #취리코 #취업리부트코스
    취업리부트
    WebFlux
    OOP
    자바
    Spring WebFlux
    SAA
    Docker-compose
    시험
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hyeseong-dev
[프로그래머스] 뒤에서 5등까지
상단으로

티스토리툴바