[BOJ/C++] 백준 2751번: 수 정렬하기 2

2024. 8. 7. 20:20·🐸 Problem Solving/BOJ

 

🔗 문제 링크 : https://www.acmicpc.net/problem/2751

 

 

🧨 시간 초과!

 

처음은 퀵 정렬로 구현하였으나 시간 초과로 실패했다. 

두 번째엔 힙 정렬로 바꾸었지만 시간 초과! 

 

#1

힙 정렬을 구현하였을 때, 시간초과의 원인은 출력방식에 있었다.

cout << n << endl;

endl을 "\n"로 바꾸니 힙 정렬 구현 코드의 수정 없이도 바로 통과되었다.

(무거운 flush 연산과 관련된 이야기인데, 조만간 따로 정리해 볼 예정이다.)

 

#2

설마! 처음에 구현했던 퀵 정렬도 혹시...? 하는 마음에 endl을 "\n"로 바꾸어 시도해 보았지만 여전히 시간초과다.🤣

나의 퀵 정렬 구현 코드를 다시 살펴보니, 피벗(pivot)을 랜덤 선택하는 과정을 넣지 않아, 최악의 pivot이 선택되는 듯 하였다. 

이후 랜덤하게 선택하도록 코드를 수정해주었더니 통과하였다. 😀

퀵 정렬에서 pivot 랜덤 선택은 일반적으로 좋은 평균 성능을 제공한다!

 

최악의 시간 복잡도를 피해라!

 

 

 


 

문제

N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.

 

 

 

 

 

입출력 예시

입출력 예시

 

입출력 예시

 

 

 


 

풀이 #1 | 힙 정렬(Heap Sort)

#include <iostream>
#include <vector>
using namespace std;

/* 배열을 (최대)힙 구조로 변환하는 함수 (재귀적) */
void heapify(vector<int>& vec, int n, int i) {
    int largest = i;        // 루트를 가장 큰 값으로 초기화
    int left = 2 * i + 1;   // 왼쪽 자식 노드
    int right = 2 * i + 2;  // 오른쪽 자식 노드

    /* 왼쪽 자식이 루트보다 큰 경우 */
    if (left < n && vec[left] > vec[largest])
        largest = left;

    /* 오른쪽 자식이 현재 가장 큰 값보다 큰 경우 */
    if (right < n && vec[right] > vec[largest])
        largest = right;

    /* 가장 큰 값이 루트가 아닌 경우 */
    if (largest != i) {
        swap(vec[i], vec[largest]);
        
        heapify(vec, n, largest);
    }
}

/* 힙에서 최대 값을 제거하며 벡터를 정렬하는 함수(힙 정렬) */
void heapSort(vector<int>& vec) {
    int n = vec.size();

    for (int i = n / 2 - 1; i >= 0; --i)
        heapify(vec, n, i);

    /* 힙에서 요소를 추출하여 정렬 */
    for (int i = n - 1; i >= 0; --i) {
        swap(vec[0], vec[i]);
        heapify(vec, i, 0);
    }
}

int main() {
    int N;
    cin >> N;

    vector<int> nums;
    for(int i = 0; i < N; ++i) {
        int num;
        cin >> num;

        nums.push_back(num);
    }

    /* 정렬 */
    heapSort(nums);

    for(int n : nums) {
        cout << n << "\n";
    }

    return 0;
}

 

 

 

풀이 #2 | 퀵 정렬(QuickSort)

  • pivot을 꼭 랜덤으로 선택해야한다.
  • 시드 값은 main() 함수가 실행되자마자 설정하도록 했다.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;

/* 백터 요소 a와 b를 바꾸어주는 함수 */
void swap(int& a, int& b) {
    int tmp = a;
    a = b;
    b = tmp;
}

/* pivot을 기준으로 벡터를 분할하는 함수 */
int partition(vector<int>& vec, int low, int high) {
    /* pivot을 랜덤으로 선택하고 마지막 요소와 교체 */
    int randomPivotIdx = low + rand() % (high - low + 1);
    swap(vec[randomPivotIdx], vec[high]);
    
    int pivot = vec[high];
    int i = low - 1;

    for (int j = low; j <= high - 1; ++j) {
        if (vec[j] < pivot) {
            ++i;
            swap(vec[i], vec[j]);
        }
    }

    swap(vec[i + 1], vec[high]);
    return (i + 1);
}

/* 재귀적으로 분할과 정렬을 하는 함수 (퀵 정렬) */
void quickSort(vector<int>& vec, int low, int high) {
    if (low < high) {
        int pivot = partition(vec, low, high);

        quickSort(vec, low, pivot - 1);
        quickSort(vec, pivot + 1, high);
    }
}

int main() {
    srand(time(0));

    int N;
    cin >> N;

    vector<int> nums;
    for(int i = 0; i < N; ++i) {
        int num;
        cin >> num;

        nums.push_back(num);
    }

    quickSort(nums, 0, nums.size() - 1);

    for(int n : nums) {
        cout << n << "\n";
    }

    return 0;
}

 

 


저작자표시 비영리 변경금지 (새창열림)

'🐸 Problem Solving > BOJ' 카테고리의 다른 글

[BOJ/C++] 백준 10989번: 수 정렬하기 3  (0) 2024.08.09
[BOJ/C++] 백준 2750번: 수 정렬하기  (0) 2024.08.07
[BOJ/C++] 백준 1003번: 피보나치 함수  (0) 2024.08.05
'🐸 Problem Solving/BOJ' 카테고리의 다른 글
  • [BOJ/C++] 백준 11931번: 수 정렬하기 4
  • [BOJ/C++] 백준 10989번: 수 정렬하기 3
  • [BOJ/C++] 백준 2750번: 수 정렬하기
  • [BOJ/C++] 백준 1003번: 피보나치 함수
Mojing_
Mojing_
매일 매일 경험치를 쌓는 모징이의 개발 블로그입니다 :) This is Mojing’s Dev Blog where she gain experience points every day. :)
  • Mojing_
    모징이의 개발 경험치
    Mojing_
  • 전체
    오늘
    어제
    • 분류 전체보기 (143)
      • 👻 Unity (5)
        • 🔧 기능 구현 (0)
        • 💡 유니티 팁 (0)
        • 📘 Unity 노트 (2)
      • 💻 Programming (14)
        • C (3)
        • C++ (9)
        • C# (0)
        • Swift (2)
      • 💾 Computer Science (16)
        • Algorithm (9)
        • Software Engineering (7)
      • 🐸 Problem Solving (108)
        • Programmers (41)
        • BOJ (67)
      • 🔋 ETC (0)
      • 💡 Quest Log (0)
  • 인기 글

  • 공지사항

  • 태그

    탐색
    Unity
    backtracking
    오블완
    CS
    sort
    BOJ
    Problem Solving
    DFS/BFS
    dynamic programming
    programmers
    티스토리챌린지
    프로그래머스
    algorithm
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Mojing_
[BOJ/C++] 백준 2751번: 수 정렬하기 2
상단으로

티스토리툴바