자바 코딩테스트 강좌, 버블 소트 프로그램 2

1. 문제 개요

이번 강좌에서는 자바를 이용한 버블 소트 알고리즘에 대한 이해를 높이고, 실제 코딩 테스트에서 자주 출제되는 문제를 해결하는 방법을 배워보겠습니다.
버블 소트는 가장 기본적인 정렬 알고리즘 중 하나로, 정렬된 데이터를 원할 때 필요한 알고리즘으로 매우 유용합니다.
이번 문제는 주어진 배열을 오름차순으로 정렬하는 것이 목표입니다.

2. 문제 설명

여러분은 다음과 같은 배열이 주어집니다:

        int[] array = {5, 2, 9, 1, 5, 6};
    

이 배열을 버블 소트 알고리즘을 사용하여 오름차순으로 정렬하는 프로그램을 작성하세요.
정렬된 결과는 다음과 같이 출력되어야 합니다:

        정렬된 배열: [1, 2, 5, 5, 6, 9]
    

3. 문제 해결 과정

3.1. 버블 소트 알고리즘 이해하기

버블 소트(Bubble Sort)는 리스트의 모든 원소를 여러 번 반복하여 인접한 원소들 간의 크기를 비교하는 방식으로 작동하는 정렬 알고리즘입니다.
두 원소의 순서가 잘못된 경우에는 서로 교환합니다. 이러한 과정을 반복하여 모든 원소가 정렬될 때까지 진행됩니다.

  • 첫 번째 패스에서 가장 큰 수가 맨 뒤로 이동합니다.
  • 그 다음 패스에서는 두 번째로 큰 수가 맨 뒤에서 두 번째 위치로 이동합니다.
  • 이런 식으로 배열이 정렬될 때까지 계속 진행합니다.

버블 소트의 시간 복잡도는 최악의 경우 O(n^2)입니다. 그러나 간단하고 이해하기 쉬운 특징 덕분에 교육적 목적으로 많이 사용됩니다.

3.2. 버블 소트 단계별 구현

이 문제를 해결하기 위해서는 아래와 같은 단계로 진행합니다:

  1. 배열의 길이를 구합니다.
  2. 이중 루프를 사용하여 배열의 모든 원소를 비교합니다.
  3. 인접한 두 원소를 비교하여 정렬되지 않은 경우 교환합니다.
  4. 모든 원소가 정렬될 때까지 반복합니다.

3.3. Java로 코드 구현하기

이제 위의 로직을 바탕으로 실제 Java 코드를 작성해보겠습니다.
아래는 버블 소트를 사용하여 배열을 정렬하는 Java 프로그램입니다:

        
public class BubbleSort {
    public static void main(String[] args) {
        int[] array = {5, 2, 9, 1, 5, 6};
        bubbleSort(array);
        System.out.print("정렬된 배열: [");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]);
            if (i < array.length - 1) {
                System.out.print(", ");
            }
        }
        System.out.println("]");
    }

    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        boolean swapped;
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // Swap arr[j] and arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            // If no two elements were swapped, break
            if (!swapped) {
                break;
            }
        }
    }
        
        

4. 코드 분석

코드를 분석해보겠습니다.
위 코드에서 main 메서드는 배열을 초기화한 후 bubbleSort 메서드를 호출합니다.
bubbleSort 메서드는 다음과 같이 작동합니다:

  • n은 배열의 길이를 저장합니다.
  • swapped 변수는 한 사이클에서 교환이 이루어졌는지를 추적하는 역할을 합니다.
  • 외부 루프(for (int i = 0; i < n - 1; i++))는 전체 사이클의 수를 결정합니다.
  • 내부 루프는 인접 원소를 비교하고, 필요시 교환합니다.
    최악의 경우 O(n^2)까지 비교를 수행할 수 있습니다.
  • 한 사이클 동안 교환이 일어나지 않으면 배열이 이미 정렬된 것이므로 더 이상의 반복을 멈춥니다. 이는 최적화된 버블 소트의 한 예입니다.

4.1. 실행 결과

프로그램을 실행하면 다음과 같은 결과가 출력됩니다:

        정렬된 배열: [1, 2, 5, 5, 6, 9]
    

5. 효율성 평가

버블 소트는 직관적이고 구현이 간단하지만, 시간 복잡도가 O(n^2)로 비효율적입니다.
대량의 데이터에 대해서는 다른 정렬 알고리즘(예: 퀵 소트, 병합 소트 등)이 더 효율적입니다.
그러나 알고리즘을 배우기 위한 기초로는 적절한 선택이며, 작은 데이터 세트에 대해서는 유용하게 사용할 수 있습니다.

6. 마무리

이번 강좌를 통해 버블 소트의 원리와 자바에서의 구현 방법을 배웠습니다.
알고리즘 문제에서는 정렬 문제에 대한 이해가 매우 중요합니다.
다양한 정렬 알고리즘을 학습하고, 상황에 맞는 알고리즘을 선택할 수 있는 능력을 기르기 위해서는 많은 연습이 필요합니다.
앞으로도 다양한 문제를 통해 알고리즘 실력을 꾸준히 향상시켜 나가시길 바랍니다.

자바 코딩테스트 강좌, 버블 소트 프로그램 1

1. 문제 제시

주어진 정수 배열을 오름차순으로 정렬하는 버블 소트(Bubble Sort) 알고리즘을 구현하시오.
버블 소트는 가장 단순한 정렬 알고리즘 중 하나로, 인접한 두 원소를 비교하여 정렬하는 방식입니다.
이 알고리즘의 기본 아이디어는 배열의 각 원소를 반복적으로 비교하여, 작은 값을 앞으로 보내는 것입니다.

2. 알고리즘 설명

버블 소트 알고리즘의 작동 방식은 다음과 같습니다:

  1. 배열의 처음부터 끝까지 두 개의 인접한 원소를 비교합니다. 첫 번째 원소가 두 번째 원소보다 크면 두 원소를 교환합니다.
  2. 배열의 끝까지 도달할 때까지 이 과정을 반복합니다.
  3. 배열의 끝까지 도달하면 가장 큰 원소는 맨 뒤로 이동하게 됩니다.
  4. 위의 과정을 배열의 크기 – 1 만큼 반복합니다. 매 반복마다 최대 값이 배열의 뒤로 이동하므로, 남은 원소에 대해 다시 비교 및 교환을 진행합니다.

3. 예시

예를 들어, 주어진 배열이 다음과 같다고 가정합시다:

[64, 34, 25, 12, 22, 11, 90]

버블 소트를 적용하면 다음과 같은 단계가 발생합니다:

  1. 1차 정렬: [34, 25, 12, 22, 11, 64, 90]
  2. 2차 정렬: [25, 12, 22, 11, 34, 64, 90]
  3. 3차 정렬: [12, 22, 11, 25, 34, 64, 90]
  4. 4차 정렬: [12, 11, 22, 25, 34, 64, 90]
  5. 5차 정렬: [11, 12, 22, 25, 34, 64, 90]

이 과정이 완료되면 배열이 오름차순으로 정렬됩니다.

4. 자바 구현

다음은 위에서 설명한 버블 소트 알고리즘을 자바로 구현한 코드입니다:


public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        boolean swapped;
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 요소 교환
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true; // 교환이 발생했음을 표시
                }
            }
            // 만약 교환이 이루어지지 않았다면 배열이 이미 정렬된 것이므로 종료
            if (!swapped) {
                break;
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        bubbleSort(arr);
        System.out.println("정렬된 배열:");
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}
    

5. 코드 설명

위 코드는 다음과 같은 주요 기능을 포함하고 있습니다:

  • bubbleSort 메소드: 배열을 입력받아 버블 소트 알고리즘을 수행하여 정렬합니다. 두 개의 중첩된 루프를 사용하여 인접한 원소를 비교하고 필요 시 교환합니다.
  • swapped 변수: 이 변수는 현재 패스에서 교환이 발생했는지에 대한 플래그 역할을 합니다. 더 이상 교환이 이루어지지 않으면 배열이 이미 정렬된 상태이므로 추가적인 패스를 생략할 수 있습니다.
  • main 메소드: 실행 시 예시 배열을 정의하고 버블 소트 메소드를 호출합니다. 정렬 완료 후 결과를 출력합니다.

6. 성능 분석

버블 소트 알고리즘의 시간 복잡도는 최악의 경우와 평균적으로 O(n^2)입니다. 즉, 배열의 길이가 n일 때, n*(n-1)/2 만큼의 비교가 필요합니다. 최선의 경우(이미 정렬된 배열)에 대해서는 O(n)의 성능을 보여줍니다. 이러한 성능 때문에 버블 소트는 작은 데이터 세트에 적합하며, 큰 데이터 세트에는 다른 정렬 알고리즘(예: 퀵 소트, 머지 소트 등)이 더 효과적입니다.

7. 코드 최적화 및 개선

버블 소트는 그 자체로 간단하고 배우기 좋은 알고리즘이지만, 성능 최적화가 가능하다는 점에서 몇 가지 개선점을 고려할 수 있습니다:

  • 스왑 플래그를 사용하여 이미 정렬된 경우를 감지할 수 있습니다.
  • 각 반복에서 배열의 마지막 요소는 이미 정렬된 상태이므로, 내부 루프의 범위를 감소시킬 수 있습니다.
  • 정렬된 상태를 확인하며 전체 루프를 줄일 수 있습니다.

8. 마무리

이번 강좌에서는 자바로 버블 소트 알고리즘을 구현해 보았습니다. 여러 가지 정렬 알고리즘 중에서 가장 단순한 형태의 알고리즘을 배우는 것은 프로그래밍의 기본 원리를 이해하는 데 큰 도움이 됩니다. 알고리즘의 기본 구조와 흐름을 이해하고, 코드로 구현해 보며 여러분의 실력을 키우시길 바랍니다. 다음 강좌에서는 더 발전된 정렬 알고리즘에 대해서 다루어 보겠습니다. 감사합니다!

자바 코딩테스트 강좌, 배열에서 K번째 수 찾기

이번 강좌에서는 자바에서 흔히 출제되는 알고리즘 문제 중 하나인 “배열에서 K번째 수 찾기” 문제를 다루어 보겠습니다. 이 문제는 주어진 배열에서 K번째로 작은 수를 찾는 것이며, 다양한 방법으로 접근할 수 있습니다. 이러한 유형의 문제를 해결하는 능력은 취업 코딩 테스트에서 매우 중요하므로, 이를 통해 코딩 실력을 한 단계 업그레이드할 수 있도록 합시다.

문제 정의

주어진 배열의 수에서 K번째로 작은 수를 찾아 반환하는 함수를 작성하시오.

입력:
- 정수 배열 arr: n (1 ≤ n ≤ 1000) 크기의 배열
- 정수 K: K는 1 이상 n 이하의 값

출력:
- 배열에서 K번째로 작은 수를 반환

예시

예를 들어, 
arr = [7, 10, 4, 3, 20, 15]이고 K = 3이라면, 
답은 7이 됩니다.

접근 방법

이 문제를 해결하기 위해 여러 가지 방법을 고려할 수 있습니다. 가장 기본적인 접근은 다음과 같습니다.

  • 정렬을 이용한 방법: 배열을 정렬한 후 K-1 번째 인덱스의 값을 반환합니다.
  • 선택 알고리즘(Quickselect): Quickselect 알고리즘을 사용하여 K번째 수를 직접 찾을 수 있습니다.
  • 힙을 이용한 방법: 최소 힙(min-heap)을 이용하여 K번째 최소값을 구할 수 있습니다.

방법 1: 정렬을 이용한 방법

가장 직관적인 방법은 배열을 정렬한 후 K-1 번째 인덱스의 값을 반환하는 것입니다. 정렬 알고리즘 중 하나를 사용하여 배열을 정렬하면 시간 복잡도는 O(n log n)입니다.

public class KthSmallestNumber {
    public static int findKthSmallest(int[] arr, int K) {
        Arrays.sort(arr);
        return arr[K - 1];
    }
    
    public static void main(String[] args) {
        int[] arr = {7, 10, 4, 3, 20, 15};
        int K = 3;
        System.out.println("K번째 작은 수: " + findKthSmallest(arr, K));  // 7
    }
}

방법 2: Quickselect 알고리즘

Quickselect 알고리즘은 빠른 정렬(Quicksort)와 유사한 과정을 통해 K번째 smallest element를 빠르게 찾는 방법입니다. 이 알고리즘은 평균적으로 O(n)의 성능을 가집니다.

Quickselect는 피벗을 선택하고, 피벗을 기준으로 작은 값과 큰 값으로 분할합니다. 이후 K번째 수가 위치할 부분을 재귀적으로 탐색합니다.

public class KthSmallestNumber {
    public static int partition(int[] arr, int left, int right, int pivotIndex) {
        int pivotValue = arr[pivotIndex];
        swap(arr, pivotIndex, right);   // 피벗을 배열의 가장 끝으로 이동
        int storeIndex = left;

        for (int i = left; i < right; i++) {
            if (arr[i] < pivotValue) {
                swap(arr, storeIndex, i);
                storeIndex++;
            }
        }
        swap(arr, storeIndex, right);  // 피벗을 제자리로 이동
        return storeIndex;              // 피벗의 최종 인덱스를 반환
    }

    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

    public static int quickSelect(int[] arr, int left, int right, int K) {
        if (left == right) {
            return arr[left];  // 배열에 한 개의 원소만 남았을 때
        }
        
        int pivotIndex = left + (right - left) / 2; 
        pivotIndex = partition(arr, left, right, pivotIndex);
        
        if (K == pivotIndex) {
            return arr[K];
        } else if (K < pivotIndex) {
            return quickSelect(arr, left, pivotIndex - 1, K);
        } else {
            return quickSelect(arr, pivotIndex + 1, right, K);
        }
    }

    public static int findKthSmallest(int[] arr, int K) {
        return quickSelect(arr, 0, arr.length - 1, K - 1);
    }

    public static void main(String[] args) {
        int[] arr = {7, 10, 4, 3, 20, 15};
        int K = 3;
        System.out.println("K번째 작은 수: " + findKthSmallest(arr, K));  // 7
    }
}

방법 3: 최소 힙을 이용한 방법

최소 힙(min-heap)은 항상 가장 작은 값이 루트에 위치하는 특성을 가지고 있습니다. 주어진 배열의 크기가 n일 때, 최소 힙으로 최소 K개의 원소를 추출하여 K번째 원소를 찾을 수 있습니다. 이 방법은 O(n + k log n)의 성능을 보입니다.

import java.util.PriorityQueue;

public class KthSmallestNumber {
    public static int findKthSmallest(int[] arr, int K) {
        PriorityQueue minHeap = new PriorityQueue<>();
        
        for (int num : arr) {
            minHeap.offer(num);
        }
        
        int kthSmallest = -1;
        for (int i = 0; i < K; i++) {
            kthSmallest = minHeap.poll();
        }
        
        return kthSmallest;
    }

    public static void main(String[] args) {
        int[] arr = {7, 10, 4, 3, 20, 15};
        int K = 3;
        System.out.println("K번째 작은 수: " + findKthSmallest(arr, K));  // 7
    }
}

결론

이번 강좌에서는 “배열에서 K번째 수 찾기”라는 문제를 통해 다양한 알고리즘 접근 방법을 살펴보았습니다. 정렬을 이용한 간단한 방법, Quickselect 알고리즘을 이용한 효율적인 방법, 그리고 최소 힙을 이용한 방법 세 가지를 소개했습니다. 알고리즘 문제 해결 능력을 기르기 위해서는 다양한 문제를 경험하고, 각각의 방법이 어떤 상황에서 최적의 성능을 보이는지에 대한 이해가 필요합니다.

이러한 문제들을 꾸준히 풀어보면서 자신만의 문제 해결 패턴과 전략을 구축해 나간다면, 코딩 테스트에서 좋은 결과를 얻을 수 있을 것입니다.

더 많은 알고리즘 문제와 그 해결책을 다루는 강좌를 통해 여러분의 코딩 실력이 한층 더 발전하기를 바랍니다.

자바 코딩테스트 강좌, 배열과 리스트

1. 서론

프로그래밍 입문자 및 개발자 지망생들에게 배열과 리스트는 기본적인 자료구조입니다. 이 두 가지 자료구조를 이해하는 것은 다양한 코딩테스트 문제에서 뛰어난 성능을 발휘하기 위해 매우 중요합니다. 이 글에서는 자바를 사용하여 배열과 리스트를 활용한 알고리즘 문제를 하나 풀어보겠습니다.

2. 문제 설명

문제: 주어진 정수 배열에서 중복된 요소를 제거하고, 남은 요소들을 정렬하여 반환하는 메소드를 작성하시오. 결과 배열은 오름차순으로 정렬되어야 하며, 중복 값은 제거되어야 합니다.

문제 요약

  • 입력: 정수 배열
  • 출력: 중복을 제거한 후 오름차순으로 정렬된 배열

3. 예제

입력: [3, 1, 2, 3, 4, 2, 1]
출력: [1, 2, 3, 4]

4. 접근 방식

이 문제를 해결하기 위해 우리는 다음과 같은 단계를 따를 것입니다:

  • 단계 1: 입력 배열에서 중복된 요소를 제거합니다.
  • 단계 2: 남은 요소들을 정렬합니다.
  • 단계 3: 최종 결과를 반환합니다.

5. 코드 구현

이제 위의 접근 방식을 바탕으로 자바 코드를 작성해 보겠습니다.

        
import java.util.Arrays;
import java.util.HashSet;

public class RemoveDuplicatesAndSort {

    public static int[] removeDuplicatesAndSort(int[] arr) {
        // HashSet을 사용하여 중복 제거
        HashSet set = new HashSet<>();
        for (int num : arr) {
            set.add(num);
        }

        // 중복 제거한 요소를 배열로 변환
        int[] uniqueArray = new int[set.size()];
        int index = 0;
        for (int num : set) {
            uniqueArray[index++] = num;
        }

        // 배열 정렬
        Arrays.sort(uniqueArray);
        return uniqueArray;
    }

    public static void main(String[] args) {
        int[] input = {3, 1, 2, 3, 4, 2, 1};
        int[] result = removeDuplicatesAndSort(input);
        System.out.println(Arrays.toString(result)); // [1, 2, 3, 4]
    }
}
        
    

코드 설명

위 코드는 removeDuplicatesAndSort라는 메소드를 정의하고 있습니다. 이 메소드는 입력 배열에서 중복된 요소를 제거하고 정렬된 배열을 반환합니다.

  • 우선 HashSet을 사용하여 중복된 정수들을 간단히 제거합니다.
  • 그리고 HashSet의 내용을 새로운 배열로 복사합니다.
  • 마지막으로 Arrays.sort를 사용하여 배열을 정렬합니다.

6. 복잡도 분석

이 알고리즘의 시간 복잡도는 다음과 같습니다:

  • 중복 제거: O(n), 여기서 n은 입력 배열의 크기입니다.
  • 정렬: O(m log m), 여기서 m은 중복 제거된 배열의 크기입니다.

따라서 전체 시간 복잡도는 O(n + m log m)입니다.

7. 결론

이번 강좌에서는 자바를 사용하여 배열과 리스트를 활용한 중복 제거 및 정렬 알고리즘을 구현해 보았습니다. 각 단계를 통해 기본적인 자료구조의 작동 방식을 이해하고, 실력을 키워나가는 방법을 배웠습니다. 앞으로도 다양한 알고리즘 문제를 해결하면서 더 많은 경험을 쌓아가길 바랍니다.

참고 문헌

  • 자료구조 및 알고리즘 관련 서적
  • Java 공식 문서

8. 추가 연습 문제

다음과 같은 문제를 추가로 시도해 보세요.

  • 정렬된 배열이 주어졌을 때, 중복된 값을 제거하고 새로운 배열을 반환하는 메소드를 구현하시오.

코딩 연습을 통해 알고리즘 이해도를 높이고, 실력을 쌓으세요!

자바 코딩테스트 강좌, 미로 탐색하기

코딩 인터뷰 및 알고리즘 테스트는 여러 후보자들에게 흔히 있는 도전 과제입니다. 그 중 하나인 미로 탐색 문제는 매우 인기 있는 알고리즘 문제로, BFS(너비 우선 탐색)와 DFS(깊이 우선 탐색)와 같은 탐색 알고리즘을 배우기에 적합합니다. 본 글에서는 자바를 사용하여 미로를 탐색하는 문제를 살펴보고, 이를 해결하기 위한 단계별 접근 방법을 설명하겠습니다.

문제 설명

주어진 2차원 배열에서, 0은 이동할 수 있는 공간을, 1은 벽을 나타냅니다. 시작 지점에서 도착 지점까지의 경로를 찾는 것입니다. 경로가 존재하면 그 경로를 출력하고, 존재하지 않으면 “경로가 없습니다.”라고 출력합니다.

문제 예시

    입력:
    [
        [0, 1, 0, 0, 0],
        [0, 1, 0, 1, 0],
        [0, 0, 0, 1, 0],
        [0, 1, 0, 0, 0],
        [0, 0, 0, 1, 0]
    ]
    시작 지점 (0, 0)
    도착 지점 (4, 4)

    출력:
    (0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) -> (3, 2) -> (4, 2) -> (4, 3) -> (4, 4)
    

해결 과정

1. 문제 이해하기

우선적으로 문제를 정확하게 이해해야 합니다. 미로를 표현하는 2차원 배열에서, 시작 지점에서 출발해 도착 지점까지 가는 경로를 찾아야 하며, 벽(1)을 지나서는 안 됩니다. 위의 예시에서는 시작 지점에서 도착 지점까지 어떤 경로를 통해 갈 수 있는지를 알아내야 합니다.

2. 탐색 알고리즘 선택하기

미로 탐색은 BFS 또는 DFS로 해결할 수 있습니다. BFS는 최단 경로를 찾는 데 유리하며, DFS는 경로를 깊게 탐색하는 데 유리합니다. 여기서는 BFS를 이용한 해결 방법을 선택하겠습니다.

3. 알고리즘 설계

BFS 알고리즘을 사용하여 다음과 같은 절차로 경로를 탐색할 것입니다:

  1. 시작 지점에서 이웃한 지점을 큐에 추가합니다.
  2. 큐에서 지점을 하나씩 꺼내면서, 해당 지점이 도착 지점인지 확인합니다.
  3. 도착 지점이 아닌 경우, 그 지점의 이웃한 지점들을 큐에 추가합니다.
  4. 모든 경로를 탐색해도 도착 지점에 도달하지 못했다면, “경로가 없습니다.”라고 출력합니다.

4. 자바 코드 구현하기

    import java.util.LinkedList;
import java.util.Queue;

public class MazeSolver {
    static class Point {
        int x, y;
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};

    public static void main(String[] args) {
        int[][] maze = {
            {0, 1, 0, 0, 0},
            {0, 1, 0, 1, 0},
            {0, 0, 0, 1, 0},
            {0, 1, 0, 0, 0},
            {0, 0, 0, 1, 0}
        };
        
        findPath(maze, new Point(0, 0), new Point(4, 4));
    }

    static void findPath(int[][] maze, Point start, Point end) {
        int n = maze.length;
        int m = maze[0].length;
        boolean[][] visited = new boolean[n][m];
        Point[][] previous = new Point[n][m];

        Queue queue = new LinkedList<>();
        queue.offer(start);
        visited[start.x][start.y] = true;

        while (!queue.isEmpty()) {
            Point current = queue.poll();
        
            if (current.x == end.x && current.y == end.y) {
                printPath(previous, start, end);
                return;
            }

            for (int i = 0; i < 4; i++) {
                int nx = current.x + dx[i];
                int ny = current.y + dy[i];

                if (nx >= 0 && nx < n && ny >= 0 && ny < m && !visited[nx][ny] && maze[nx][ny] == 0) {
                    visited[nx][ny] = true;
                    previous[nx][ny] = current;
                    queue.offer(new Point(nx, ny));
                }
            }
        }

        System.out.println("경로가 없습니다.");
    }

    static void printPath(Point[][] previous, Point start, Point end) {
        StringBuilder path = new StringBuilder();
        for (Point at = end; at != null; at = previous[at.x][at.y]) {
            path.insert(0, String.format("-> (%d, %d) ", at.x, at.y));
        }
        System.out.println(path.substring(4)); // 처음의 "-> " 제거
    }
}

    

5. 코드 설명

위의 코드에서는 BFS 알고리즘을 구현하였습니다. Point라는 내부 클래스를 사용해 (x, y) 좌표를 정의하여 큐와 경로 추적에 활용합니다. 큐에는 현재 위치의 이웃 좌표를 추가하며, 방문한 지점은 visited 배열에서 체크하여 중복 탐색을 방지합니다. 도착 지점에 도달하면, printPath 메서드가 호출되어 경로를 출력합니다.

6. 코드 실행 결과

    (0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) -> (3, 2) -> (4, 2) -> (4, 3) -> (4, 4)
    

마무리

이제 미로 탐색 문제를 해결하는 방법에 대해 배우셨습니다. 이 알고리즘은 다양한 문제에 적용할 수 있는 유용한 기술입니다. 문제를 해결하기 위해 탐색 알고리즘의 기초를 이해하고, 이를 자바로 구현하는 과정은 매우 유익한 경험이 될 것입니다. 여러분의 코딩 테스트 준비에 도움이 되길 바랍니다!