본문 바로가기
-----ETC-----/C++로 배우는 알고리즘과 자료구조 시리즈

[C++로 배우는 알고리즘과 자료구조] Day 30: 알고리즘 문제 해결 및 코딩 테스트 준비

by cogito21_cpp 2024. 8. 1.
반응형

알고리즘 문제 해결 및 코딩 테스트 준비

코딩 테스트는 프로그래밍 실력을 검증하기 위한 중요한 과정입니다. 알고리즘과 자료구조를 잘 이해하고, 다양한 문제를 해결할 수 있는 능력을 갖추는 것이 중요합니다. 오늘은 알고리즘 문제 해결 및 코딩 테스트 준비에 필요한 몇 가지 팁과 예제를 다루겠습니다.

코딩 테스트 준비 팁

  1. 기본기 다지기:
    • 알고리즘과 자료구조의 기본 개념을 확실히 이해합니다.
    • 배열, 문자열, 스택, 큐, 링크드 리스트, 해시 테이블, 트리, 그래프 등을 학습합니다.
  2. 다양한 문제 풀기:
    • 다양한 알고리즘 문제를 풀어보며 문제 해결 능력을 키웁니다.
    • LeetCode, HackerRank, CodeSignal, Programmers와 같은 온라인 플랫폼에서 문제를 풉니다.
  3. 시간 복잡도와 공간 복잡도 이해:
    • 알고리즘의 효율성을 평가하는 방법을 이해합니다.
    • 최적의 알고리즘을 선택할 수 있는 능력을 기릅니다.
  4. 코드 작성 연습:
    • 문제를 해결한 후, 최적의 코드를 작성하는 연습을 합니다.
    • 코드의 가독성을 높이고, 주석을 적절히 사용합니다.
  5. 모의 면접:
    • 실제 면접과 유사한 환경에서 문제를 해결하는 연습을 합니다.
    • 친구나 온라인 플랫폼을 통해 모의 면접을 경험합니다.

예제 문제 해결

예제 문제 1: 두 수의 합 (Two Sum)

주어진 배열에서 두 수의 합이 목표 값이 되는 인덱스 쌍을 찾으세요.

 

문제 설명:

  • 입력: 정수 배열 nums와 정수 target
  • 출력: 두 수의 합이 target이 되는 인덱스 i, j (i < j)

예제 입력:

  • nums = [2, 7, 11, 15], target = 9
  • 출력: [0, 1] (nums[0] + nums[1] = 2 + 7 = 9)

해결 방법:

  • 해시 테이블을 사용하여 시간 복잡도를 (O(n))으로 줄일 수 있습니다.
#include <iostream>
#include <vector>
#include <unordered_map>

// 두 수의 합을 찾는 함수
std::vector<int> twoSum(const std::vector<int>& nums, int target) {
    std::unordered_map<int, int> numMap; // 값과 인덱스를 저장할 해시 테이블

    for (int i = 0; i < nums.size(); ++i) {
        int complement = target - nums[i];

        // 목표 값을 찾은 경우
        if (numMap.find(complement) != numMap.end()) {
            return {numMap[complement], i};
        }

        // 해시 테이블에 현재 값과 인덱스 저장
        numMap[nums[i]] = i;
    }

    return {}; // 합이 목표 값이 되는 인덱스 쌍이 없는 경우
}

int main() {
    std::vector<int> nums = {2, 7, 11, 15};
    int target = 9;
    std::vector<int> result = twoSum(nums, target);

    if (!result.empty()) {
        std::cout << "두 수의 합이 " << target << "이 되는 인덱스: [" << result[0] << ", " << result[1] << "]" << std::endl;
    } else {
        std::cout << "두 수의 합이 " << target << "이 되는 인덱스 쌍이 없습니다." << std::endl;
    }

    return 0;
}

 

예제 문제 2: 회문 연결 리스트 (Palindrome Linked List)

주어진 연결 리스트가 회문인지 확인하세요.

 

문제 설명:

  • 입력: 단일 연결 리스트의 헤드 노드
  • 출력: 회문이면 true, 아니면 false

예제 입력:

  • 입력: 1 -> 2 -> 2 -> 1
  • 출력: true

해결 방법:

  • 연결 리스트를 중간에서 나누고, 후반부를 뒤집어서 비교합니다.
#include <iostream>

// 연결 리스트 노드 구조체 정의
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

// 연결 리스트 회문 확인 함수
bool isPalindrome(ListNode* head) {
    if (head == nullptr || head->next == nullptr) {
        return true;
    }

    // 중간 지점 찾기 (빠른/느린 포인터 사용)
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast->next != nullptr && fast->next->next != nullptr) {
        slow = slow->next;
        fast = fast->next->next;
    }

    // 후반부 뒤집기
    ListNode* prev = nullptr;
    ListNode* curr = slow->next;
    while (curr != nullptr) {
        ListNode* nextTemp = curr->next;
        curr->next = prev;
        prev = curr;
        curr = nextTemp;
    }

    // 전반부와 후반부 비교
    ListNode* first = head;
    ListNode* second = prev;
    while (second != nullptr) {
        if (first->val != second->val) {
            return false;
        }
        first = first->next;
        second = second->next;
    }

    return true;
}

int main() {
    // 연결 리스트 생성
    ListNode* head = new ListNode(1);
    head->next = new ListNode(2);
    head->next->next = new ListNode(2);
    head->next->next->next = new ListNode(1);

    if (isPalindrome(head)) {
        std::cout << "연결 리스트는 회문입니다." << std::endl;
    } else {
        std::cout << "연결 리스트는 회문이 아닙니다." << std::endl;
    }

    // 연결 리스트 메모리 해제
    while (head != nullptr) {
        ListNode* temp = head;
        head = head->next;
        delete temp;
    }

    return 0;
}

 

마무리

알고리즘 문제 해결 및 코딩 테스트 준비는 꾸준한 연습과 반복 학습이 필요합니다. 다양한 문제를 풀어보고, 효율적인 알고리즘을 설계하는 능력을 키우세요. 여러분의 코딩 테스트 준비에 도움이 되었기를 바랍니다.

이제 C++로 배우는 알고리즘과 자료구조 시리즈의 30일 과정을 마쳤습니다. 질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 모두 수고하셨습니다!

반응형