C# 코딩테스트 강좌, 효율적으로 해킹하기

코딩 테스트는 많은 소프트웨어 개발자와 엔지니어들이 진입 장벽을 통과하기 위해 거쳐야 하는 필수적인 과정입니다. 이 글에서는 C#을 활용하여 코딩 테스트에서 자주 나오는 알고리즘 문제를 해결하는 방법을 다루어 보겠습니다. 특히 효율적인 해킹 과정이 무엇인지, 그리고 이를 위해 필요한 알고리즘 패턴에 대해 알아보겠습니다.

문제: 두 숫자의 합

주어진 정수 배열과 목표 정수 ‘target’이 있을 때, 배열 안에서 두 숫자의 합이 그 ‘target’과 동일한 인덱스를 찾으세요. 인덱스는 0부터 시작하며, 각 숫자는 딱 한 번만 사용해야 합니다.

예시 입력

nums = [2, 7, 11, 15]
target = 9

예시 출력

[0, 1]

문제 해석

위의 문제는 상당히 유명한 ‘Two Sum’ 문제입니다. 주어진 배열에서 두 개의 수를 선택해 그 합이 주어진 목표값과 같아야만 합니다. 이 문제는 다양한 방법으로 접근할 수 있지만, 여기서는 효율적인 접근 방식을 중점적으로 설명할 것입니다.

접근 방식

1. **Brute Force (무차별 대입법)**: 배열의 모든 가능한 쌍을 검사하여 합이 ‘target’과 일치하는지 확인하는 방식입니다. 그러나 이 방법은 시간복잡도가 O(n^2)로 매우 비효율적입니다.

2. **해시맵을 사용하는 방법**: 해시맵을 사전 형태로 사용하여, 우리가 현재 보고 있는 숫자의 보완 숫자 (target – 현재 숫자)를 저장하는 방법입니다. 이 방법은 O(n) 시간복잡도로 문제를 해결할 수 있습니다.

구현

C# 코드 구현

using System;
using System.Collections.Generic;

public class Solution
{
    public int[] TwoSum(int[] nums, int target)
    {
        Dictionary map = new Dictionary();

        for (int i = 0; i < nums.Length; i++)
        {
            int complement = target - nums[i];
            if (map.ContainsKey(complement))
            {
                return new int[] { map[complement], i };
            }
            map[nums[i]] = i;
        }
        throw new ArgumentException("No two sum solution");
    }
}
    

코드 설명

  • 우선, 빈 해시맵(<Dictionary>)을 생성합니다. 이 맵은 숫자를 키로 하고 그 숫자의 인덱스를 값으로 저장할 것입니다.
  • 배열을 순회하면서 각 숫자에 대해 그 숫자의 보완 숫자를 계산하고, 이미 해시맵에 존재하는지 체크합니다.
  • 존재한다면, 그 보완 숫자의 인덱스와 현재 인덱스를 반환합니다.
  • 존재하지 않는다면, 현재 숫자와 인덱스를 해시맵에 추가합니다.
  • 이 동작을 배열의 모든 숫자에 대해 반복합니다.

실행 예시

실행 시 주어진 nums와 target을 기반으로 다음과 같은 결과를 도출하게 됩니다:

var solution = new Solution();
var result = solution.TwoSum(new int[] { 2, 7, 11, 15 }, 9);
Console.WriteLine(string.Join(", ", result)); // Output: 0, 1
    

효율성을 높이기 위한 팁

코딩 테스트에서 데이터 구조와 알고리즘을 선택할 때는 각 경우에 적합한 것을 선택하는 것이 중요합니다. 아래는 고려해야 할 몇 가지 팁입니다.

  • **시간 복잡도**: 알고리즘의 실행 시간을 고려하십시오. 가장 빠른 알고리즘을 선택할수록 좋습니다.
  • **공간 복잡도**: 메모리 사용량을 고려하십시오. 추가적인 배열이나 리스트를 사용하는 것이 아니라, 기존의 배열이나 리스트를 활용하는 것이 좋습니다.
  • **테스트 케이스를 다양하게**: 다양한 경우의 수를 테스트하여 일반성과 안정성을 높이십시오.

결론

C#을 활용한 코딩테스트 준비는 어떤 알고리즘이 가장 효율적으로 문제를 해결하는지를 이해하는 것이 핵심입니다. 이번 강좌에서는 ‘Two Sum’ 문제를 통해 기본적인 해시맵을 활용한 기법을 설명했습니다. 앞으로 더욱 다양한 알고리즘 문제를 풀며 경험을 쌓아가길 바랍니다.

마지막으로, 코딩 테스트는 단순한 문제 해결 능력뿐 아니라, 문제를 이해하고 효과적인 해결책을 찾는 사고 과정을 포함합니다. 이러한 기술은 개발자로서의 경로에서 매우 중요한 부분이라는 점을 잊지 마세요.

참고자료

C# 코딩테스트 강좌, 시간 복잡도 활용하기

안녕하세요, 블로그를 방문해 주신 여러분! 오늘은 C#을 활용한 코딩테스트에서 흔히 마주하는 알고리즘 문제를 풀어보며 시간 복잡도의 개념에 대해 깊이 탐구해 보겠습니다. 코딩테스트는 현대 프로그래밍 인터뷰에서 필수적인 요소로 자리잡고 있으며, 문제를 푸는 데 있어서 알고리즘과 데이터 구조에 대한 이해는 물론, 시간 복잡도를 계산하는 능력이 반드시 필요합니다. 이번 글에서는 실제 알고리즘 문제를 통해 이러한 내용을 자세하게 설명할 것입니다.

문제: 두 수의 합

문제 설명:
주어진 정수 배열 nums와 정수 target가 있을 때, nums에서 두 수를 찾아 그 합이 target이 되는 두 수의 인덱스를 반환하는 함수를 작성하시오. 각 입력에 대해서는 정확히 하나의 해가 존재한다고 가정하고, 같은 요소를 두 번 사용할 수는 없습니다.

public int[] TwoSum(int[] nums, int target) {
    // 구현할 코드
}

예제 입력

nums = [2, 7, 11, 15]
target = 9

예제 출력

[0, 1]

문제 풀이

이 문제는 비교적 간단한 알고리즘 문제입니다. 하지만 시간 복잡도를 고려하여 효율적인 방법으로 해결하는 것이 중요합니다. 여러 가지 접근 방식이 있지만, 여기서는 해시맵(HashMap)을 이용한 접근 방식을 소개하겠습니다.

풀이 과정

  1. 주어진 배열을 순회하면서, 각 숫자에 대해 target과의 차이를 계산합니다.
  2. 이 차이가 해시맵에 존재하는지 확인합니다. 만약 존재한다면 해당 인덱스와 현재 인덱스를 반환합니다.
  3. 해시맵에 현재 숫자와 인덱스를 추가합니다.

시간 복잡도 분석

해시맵을 이용한 이 접근 방식의 시간 복잡도는 O(n)입니다. 각 요소를 한 번씩만 확인하므로, 효율적입니다. 공간 복잡도는 해시맵에 저장되는 숫자 때문인 O(n)입니다.

C# 코드 구현

public int[] TwoSum(int[] nums, int target) {
    Dictionary numDict = new Dictionary();

    for (int i = 0; i < nums.Length; i++) {
        int complement = target - nums[i];
        if (numDict.ContainsKey(complement)) {
            return new int[] { numDict[complement], i };
        }
        numDict[nums[i]] = i;
    }
    throw new ArgumentException("No two sum solution");
}

결과

이제 위의 코드를 실행하면 주어진 배열에서 원하는 두 수의 인덱스를 찾을 수 있습니다. 이 예제에서는 nums = [2, 7, 11, 15]에 대해 target = 9인 경우, 출력은 [0, 1]입니다.

시간 복잡도의 의의와 활용

알고리즘 문제를 해결할 때 시간이 중요한 이유는 여러 가지가 있습니다. 특히 유한한 시간 내에 문제를 해결해야 하는 코딩테스트나 실제로 운영할 시스템에서는 실행 시간이 매우 중요한 요소로 작용합니다.

시간 복잡도를 분석할 때는 다음과 같은 방법을 활용합니다:

  • 상수 시간 복잡도 (O(1)): 입력의 크기와 관계없이 항상 일정한 시간 내에 결과를 반영할 수 있는 알고리즘입니다.
  • 로그 시간 복잡도 (O(log n)): 입력의 크기가 두 배가 되어도 알고리즘의 수행 시간은 일정 비율로 늘어나는 경우입니다. 이진 검색 알고리즘이 대표적입니다.
  • 선형 시간 복잡도 (O(n)): 입력의 크기에 비례하여 수행 시간이 증가하는 알고리즘입니다. 주어진 배열의 모든 원소를 한 번씩 확인하는 경우가 여기에 해당합니다.
  • 선형 로그 시간 복잡도 (O(n log n)): 입력 크기에 로그를 곱한 형태의 복잡도입니다. 병합 정렬이나 퀵 정렬 알고리즘이 이에 해당합니다.
  • 다항 시간 복잡도 (O(n^k)): 입력 크기의 k 제곱에 비례하여 성능이 저하되는 경우입니다. 이중 루프를 사용하는 경우가 이에 해당합니다.
  • 지수 시간 복잡도 (O(2^n)): 입력 크기가 작더라도 빠르게 수행 시간이 급격히 증가하는 알고리즘입니다. 피보나치 수열을 재귀적으로 계산할 때 등이 있습니다.

알고리즘 문제를 풀 때 고려사항

문제를 풀 때 다음 사항을 염두에 두어야 합니다:

  • 입력의 범위와 특성을 이해한다.
  • 문제를 단계별로 나누어 해결할 수 있는 방법을 생각한다.
  • 시간 복잡도와 공간 복잡도를 최대한 최소화하는 방향으로 구현한다.
  • 가능하다면 다양한 테스트 케이스를 고려하여 알고리즘의 정확성을 검증한다.

최종 검토

이상으로, C# 코딩테스트에서 시간 복잡도를 활용하는 방법과 문제 해결 과정을 살펴보았습니다. 두 수의 합 문제를 비롯한 다양한 알고리즘 문제를 풀어보며 시간 복잡도를 잘 활용하는 연습을 해보시기 바랍니다. 향후 코딩테스트에서 좋은 결과를 얻기를 바랍니다!

마무리

이 글이 C# 코딩테스트를 준비하는 데 유용한 길잡이가 되었기를 바라며, 지속적으로 문제를 풀고 시간 복잡도를 고려하여 더 효과적인 코드를 작성하는 연습을 하시길 추천드립니다. 추가적인 질문이나 피드백이 있다면 언제든지 댓글로 남겨주세요!

감사합니다!

C# 코딩테스트 강좌, DFS와 BFS 프로그램

소프트웨어 개발자로 취업하기 위해서는 알고리즘 시험이 중요합니다. 특히 DFS(Depth-First Search)와 BFS(Breadth-First Search)는 그래프 탐색의 기본 개념으로, 많은 문제에서 활용됩니다. 이 글에서는 DFS와 BFS 알고리즘을 사용한 문제를 소개하고, 문제 해결 과정을 자세히 설명하겠습니다.

문제 설명

가장 먼저, 다음과 같은 그래프가 있다고 가정해봅시다. 이 그래프는 정점(Vertex)과 간선(Edge)으로 구성되어 있습니다. 다음 그래프를 탐색하여 특정 정점을 찾는 문제를 해결해보겠습니다.

문제

그래프가 주어질 때, 주어진 시작 정점에서 특정 정점을 찾기 위한 DFS와 BFS 알고리즘을 구현하시오.

입력

  • 정점의 수: n (2 ≤ n ≤ 100)
  • 간선의 수: m (1 ≤ m ≤ 300)
  • 간선의 목록: 각 간선은 두 정점으로 구성됨 (u, v)
  • 시작 정점: start
  • 찾고자 하는 정점: target

출력

시작 정점에서부터 target 정점까지 도달할 수 있으면 true, 없으면 false를 출력합니다.

문제 풀이

이번 문제는 DFS와 BFS 알고리즘을 통해 해결할 수 있습니다. 두 방법 모두 그래프 탐색을 위해 널리 사용되는 기법입니다. 두 알고리즘의 동작 원리를 먼저 살펴보겠습니다.

DFS(Depth-First Search)

DFS는 깊이 우선 탐색으로, 한 노드를 깊게 탐색한 뒤 더 이상 탐색할 노드가 없으면 뒤로 돌아와 다른 노드를 탐색하는 방식입니다. 스택을 사용하여 구현할 수 있습니다.

BFS(Breadth-First Search)

BFS는 너비 우선 탐색으로, 한 노드의 모든 이웃 노드를 탐색한 뒤, 다음 이웃 노드를 탐색하는 방식입니다. Queue 자료구조를 사용하여 구현할 수 있습니다.

구현

이제 C#으로 DFS와 BFS 알고리즘을 구현해보겠습니다.

1. 그래프 표현

그래프는 인접 리스트 형태로 표현할 수 있습니다. 각 노드에 대해 연결된 노드를 리스트 형태로 저장합니다.


public class Graph
{
    private int vertices; // 정점의 수
    private List[] adjList; // 인접 리스트

    public Graph(int n)
    {
        this.vertices = n;
        adjList = new List[n];
        for (int i = 0; i < n; i++)
        {
            adjList[i] = new List();
        }
    }

    // 간선 추가 메소드
    public void AddEdge(int u, int v)
    {
        adjList[u].Add(v);
        adjList[v].Add(u); // 무향 그래프
    }

    public List GetNeighbors(int vertex)
    {
        return adjList[vertex];
    }
}

2. DFS 구현

DFS는 다음과 같이 재귀적인 방법으로 구현할 수 있습니다.


public class DFS
{
    private bool[] visited;
    private Graph graph;

    public DFS(Graph g)
    {
        this.graph = g;
        this.visited = new bool[g.vertices];
    }

    public bool Search(int start, int target)
    {
        // 현재 노드를 방문 처리
        if (start == target) return true;
        visited[start] = true;

        foreach (int neighbor in graph.GetNeighbors(start))
        {
            if (!visited[neighbor] && Search(neighbor, target))
            {
                return true; // 타겟 발견
            }
        }
        return false; // 타겟 발견하지 못함
    }
}

3. BFS 구현

BFS는 Queue를 사용하여 다음 노드를 탐색하는 방식으로 구현합니다.


using System.Collections.Generic;

public class BFS
{
    private bool[] visited;
    private Graph graph;

    public BFS(Graph g)
    {
        this.graph = g;
        this.visited = new bool[g.vertices];
    }

    public bool Search(int start, int target)
    {
        Queue queue = new Queue();
        queue.Enqueue(start);
        visited[start] = true;

        while (queue.Count > 0)
        {
            int current = queue.Dequeue();
            if (current == target) return true;

            foreach (int neighbor in graph.GetNeighbors(current))
            {
                if (!visited[neighbor])
                {
                    queue.Enqueue(neighbor);
                    visited[neighbor] = true;
                }
            }
        }
        return false; // 타겟 발견하지 못함
    }
}

테스트 케이스

이제 구현한 알고리즘을 테스트하기 위해, 간단한 그래프를 만들어 보겠습니다.


public class MainClass
{
    public static void Main(string[] args)
    {
        Graph graph = new Graph(5);
        graph.AddEdge(0, 1);
        graph.AddEdge(0, 2);
        graph.AddEdge(1, 3);
        graph.AddEdge(1, 4);
        graph.AddEdge(2, 4);

        DFS dfs = new DFS(graph);
        BFS bfs = new BFS(graph);

        Console.WriteLine("DFS: " + dfs.Search(0, 4)); // true
        Console.WriteLine("BFS: " + bfs.Search(0, 4)); // true

        Console.WriteLine("DFS (No path): " + dfs.Search(0, 5)); // false
        Console.WriteLine("BFS (No path): " + bfs.Search(0, 5)); // false
    }
}

종합 정리

이번 강좌에서는 DFS와 BFS 알고리즘을 통해 그래프 탐색 문제를 해결하는 방법을 살펴보았습니다. 각각의 탐색 방법은 장점과 단점이 있으며, 문제의 성격에 따라 적절한 방법을 선택해야 합니다. DFS는 메모리 사용이 적고, 깊이 있는 문제를 해결할 때 유리하지만 경로를 찾는 데 시간이 더 걸릴 수 있습니다. 반면, BFS는 최단 경로를 찾는 데 유리하지만, 메모리 사용량이 많을 수 있습니다.

이 기사를 통해 DFS와 BFS를 이해하고, 다양한 코딩 테스트 문제에 대응할 수 있는 역량을 기르기를 바랍니다.

참고 자료

결론

코딩테스트는 개발자로서의 기본 역량을 평가하는 중요한 과정입니다. DFS와 BFS 알고리즘은 그래프 탐색의 기초적인 방법으로, 기본기를 다지는 데 큰 도움이 됩니다. 다양한 알고리즘과 자료구조를 익히고, 연습을 통해 실력을 키워나가길 바랍니다.

C# 코딩테스트 강좌, 나머지 합 구하기

문제 설명

주어진 정수 배열 numbers와 정수 target이 있다.
numbers 배열의 원소 중에서 어떤 두 원소를 합하여 나머지가 target이 되도록 할 수 있는지를 확인해야 한다.
가능한 경우에는 그 두 원소의 인덱스를 반환하고, 그렇지 않으면 -1을 반환하시오.
단, 각 원소는 한 번만 사용해야 하며, 같은 원소를 두 번 선택할 수 없다.

입력 형식

  • numbers: 정수 배열 (0 ≤ numbers.length ≤ 105, -109 ≤ numbers[i] ≤ 109)
  • target: 정수 (0 ≤ target ≤ 109)

출력 형식

두 원소의 인덱스 또는 -1

문제 풀이 과정

1. 문제 분석

이 문제는 특이하게 두 원소를 더한 후 나머지 연산을 통해 target을 얻는 문제입니다. 즉,
우리가 찾고자 하는 두 수 xy가 있을 때,
(x + y) % target == target이어야 합니다. 여기서 더하기와 나머지 조건이 가지는 의미를 잘 이해해야 합니다.

2. 알고리즘 설계

이 문제를 해결하기 위해 배열을 한 번만 순회하면서, 각 원소를 목표 식에 맞추어 나머지를 계산하겠습니다.
한 가지 방법으로는 해시셋을 사용하여 과거의 값들을 저장하고, 현재 값과 함께 나머지를 계산하여 조건을 확인하는 방법입니다.
해시셋을 사용하는 이유는 평균적인 시간복잡도를 O(1)로 유지할 수 있기 때문입니다.

3. 코드 작성

이제 이러한 알고리즘을 C#로 구현해 보겠습니다. 아래는 해결책 코드입니다.

using System;
using System.Collections.Generic;

public class Solution
{
    public int[] FindTwoElementsWithTargetModulo(int[] numbers, int target)
    {
        // 원소의 위치를 저장하기 위한 딕셔너리
        Dictionary valueToIndex = new Dictionary();
        
        for (int i = 0; i < numbers.Length; i++)
        {
            // 현재 원소에 대해 나머지 값을 계산
            int requiredValue = (target - numbers[i]) % target;

            // 이미 나머지 값이 딕셔너리에 존재하는지 확인
            if (valueToIndex.ContainsKey(requiredValue))
            {
                return new int[] { valueToIndex[requiredValue], i };
            }

            // 현재 원소를 딕셔너리에 기록
            if (!valueToIndex.ContainsKey(numbers[i]))
            {
                valueToIndex[numbers[i]] = i;
            }
        }
        
        // 조건을 만족하는 두 원소가 없는 경우
        return new int[] { -1 };
    }
}
        

4. 시간 복잡도

이 알고리즘의 시간 복잡도는 O(n)입니다. 한 번의 배열 순회로 결과를 찾을 수 있습니다.
또한 추가적인 공간 복잡도는 O(n)으로, 해시셋을 사용하여 값을 저장하기 때문입니다.

5. 테스트 케이스

다양한 테스트 케이스를 작성하여 작동 여부를 확인해보겠습니다.

public class Program
{
    public static void Main()
    {
        Solution solution = new Solution();

        // 테스트 케이스 1
        int[] numbers1 = { 1, 2, 3, 4, 5 };
        int target1 = 5;
        int[] result1 = solution.FindTwoElementsWithTargetModulo(numbers1, target1);
        Console.WriteLine(string.Join(", ", result1)); // 예상 출력: 0, 4

        // 테스트 케이스 2
        int[] numbers2 = { 1, 2, 3, 7 };
        int target2 = 5;
        int[] result2 = solution.FindTwoElementsWithTargetModulo(numbers2, target2);
        Console.WriteLine(string.Join(", ", result2)); // 예상 출력: 0, 2

        // 테스트 케이스 3
        int[] numbers3 = { 3, 8, 12, 5 };
        int target3 = 10;
        int[] result3 = solution.FindTwoElementsWithTargetModulo(numbers3, target3);
        Console.WriteLine(string.Join(", ", result3)); // 예상 출력: -1
    }
}
        

6. 맺음말

이번 강좌에서는 나머지 합을 구하는 문제를 해결하기 위해 해시셋을 사용하여 공간과 시간을 최적화하는 방법을 학습했습니다.
코딩 테스트에서 나오는 다양한 문제를 풀기 위해서는 이러한 접근 방식이 매우 유용합니다.
더 많은 알고리즘 문제를 풀며 자신감을 쌓아 나가길 바랍니다.

C# 코딩테스트 강좌, 수 정렬하기 2

문제 설명

주어진 수를 정렬하는 프로그램을 작성하시오.
입력은 표준 입력을 통해 주어지며, 첫 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다.
이어서 N개의 자연수가 입력된다. 이 숫자들은 구분되어 공백으로 입력되며,
주어진 숫자들은 0보다 크거나 같고 10,000보다 작거나 같은 정수이다.
정렬된 결과를 출력하시오.

입력 예시

    5
    5 2 3 1 4
    

출력 예시

    1
    2
    3
    4
    5
    

문제 해결 과정

1. 문제 이해

수를 정렬하는 문제는 기본적인 알고리즘 중 하나로, 많은 경우에서 다뤄지는 주제이다.
이 문제에서 요구하는 것은 주어진 수를 오름차순으로 정렬하여 출력하는 것이다.
배열 또는 리스트와 같은 자료구조를 사용하여 입력된 숫자를 저장하고 정렬 방법을 사용하여
정렬할 수 있다.

2. 입력 처리

입력은 첫 번째 줄에 숫자의 개수 N이 주어지고, 그 다음 줄에는 N개의 정수가 주어진다.
이는 C#에서 Console.ReadLine() 메소드를 통해 읽을 수 있다.

3. 정렬 알고리즘 선택

C#에서는 내장된 정렬 메소드인 Array.Sort()와 List.Sort()를 사용할 수 있다.
이 두 메소드는 평균적으로 O(N log N)의 시간 복잡도를 가진다.
제한된 입력 범위 안에서 매우 효율적이며, 문제에서 요구하는 성능을 충족한다.

4. 알고리즘 구현

아래는 C#으로 구현한 수 정렬하기 2의 코드 예시이다.

        using System;

        class Program
        {
            static void Main()
            {
                // 입력 받기
                int n = int.Parse(Console.ReadLine());
                int[] numbers = new int[n];

                // 숫자 입력받기
                string[] input = Console.ReadLine().Split(' ');
                for (int i = 0; i < n; i++)
                {
                    numbers[i] = int.Parse(input[i]);
                }

                // 정렬하기
                Array.Sort(numbers);

                // 정렬된 결과 출력
                foreach (int number in numbers)
                {
                    Console.WriteLine(number);
                }
            }
        }
    

5. 코드 설명

int n = int.Parse(Console.ReadLine());: 사용자가 입력한 숫자의 개수를 읽어온다.
int[] numbers = new int[n];: 입력 받을 배열을 선언한다.
string[] input = Console.ReadLine().Split(‘ ‘);: 입력한 숫자들을 공백으로 구분하여 배열로 나눈다.
Array.Sort(numbers);: 내장 메소드를 사용하여 숫자를 정렬한다.
foreach (int number in numbers): 정렬된 숫자를 하나씩 출력한다.

6. 성능 분석

이 알고리즘은 O(N log N)의 시간 복잡도를 가지므로, 최대 100,000개의 수를 정렬할 때도 효율적이다.
정렬 후 출력은 O(N)의 시간 복잡도를 가지므로, 전체적으로 O(N log N)의 성능으로 문제를 해결할 수 있다.

7. 추가 고려 사항

대량의 데이터가 주어질 때, 메모리 사용도 중요한 요소이므로 메모리 효율성을 고려해야 한다.
C#에서 기본적인 유형 사용 및 내장 메소드를 사용하면 메모리 사용을 최적화할 수 있다.

8. 결론

이번 강좌에서는 C#을 사용하여 수를 정렬하는 문제를 해결하였다.
알고리즘 문제 해결 능력을 기르려면 여러 유형의 문제에 대해 반복적으로 연습해야 하며,
다양한 정렬 알고리즘에 대해서도 이해하도록 노력하는 것이 좋다.
다음 강좌에서는 더 복잡한 알고리즘 문제를 다룰 예정이다.