본문으로 건너뛰기 Coding Test Complete Preparation Complete Guide

Coding Test Complete Preparation Complete Guide

Coding Test Complete Preparation Complete Guide

이 글의 핵심

Systematically organize coding test preparation strategy. Detailed explanation of essential algorithms, data structures, problem-solving patterns, time management, and language selection with practical tips.

Introduction: Coding Tests Are All About Preparation

”I Failed Because I Didn’t Know Algorithms”

Coding tests are pattern recognition. Anyone can pass by learning frequently appearing patterns and practicing repeatedly. What This Guide Covers:

  • Essential algorithms and data structures
  • Problem-solving patterns
  • Time management strategy
  • Language selection guide
  • Practical tips

Table of Contents

  1. Essential Algorithms
  2. Essential Data Structures
  3. Problem-Solving Patterns
  4. Time Management
  5. Language Selection
  6. Practical Tips
  7. Summary

1. Essential Algorithms

Learning Order by Priority

graph TB
    A[Coding Test Algorithms] --> B[Stage 1: Essential]
    A --> C[Stage 2: Important]
    A --> D[Stage 3: Advanced]
    
    B --> B1[Two Pointers]
    B --> B2[Sliding Window]
    B --> B3[Binary Search]
    B --> B4[BFS/DFS]
    
    C --> C1[Dynamic Programming]
    C --> C2[Greedy]
    C --> C3[Backtracking]
    
    D --> D1[Shortest Path]
    D --> D2[Topological Sort]
    D --> D3[Trie]

Stage 1: Essential Algorithms (High Frequency)

Two Pointers:

# Example: Two sum in sorted array
def two_sum(arr, target):
    left, right = 0, len(arr) - 1
    
    while left < right:
        current_sum = arr[left] + arr[right]
        if current_sum == target:
            return [left, right]
        elif current_sum < target:
            left += 1
        else:
            right -= 1
    
    return None
# Time complexity: O(n)

Sliding Window:

# Example: Maximum sum subarray of length k
def max_sum_subarray(arr, k):
    window_sum = sum(arr[:k])
    max_sum = window_sum
    
    for i in range(k, len(arr)):
        window_sum += arr[i] - arr[i - k]
        max_sum = max(max_sum, window_sum)
    
    return max_sum
# Time complexity: O(n)

Binary Search:

# Example: Find value in sorted array
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    
    return -1
# Time complexity: O(log n)

BFS/DFS (Breadth/Depth First Search):

from collections import deque
# BFS
def bfs(graph, start):
    visited = set()
    queue = deque([start])
    visited.add(start)
    
    while queue:
        node = queue.popleft()
        print(node)
        
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
# DFS (recursive)
def dfs(graph, node, visited=None):
    if visited is None:
        visited = set()
    
    visited.add(node)
    print(node)
    
    for neighbor in graph[node]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)

Stage 2: Important Algorithms

Dynamic Programming (DP):

# Example: Fibonacci sequence
def fibonacci(n):
    if n <= 1:
        return n
    
    dp = [0] * (n + 1)
    dp[1] = 1
    
    for i in range(2, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    
    return dp[n]
# Time complexity: O(n)
# Space complexity: O(n)

Greedy:

# Example: Coin change
def coin_change(coins, amount):
    coins.sort(reverse=True)
    count = 0
    
    for coin in coins:
        if amount >= coin:
            count += amount // coin
            amount %= coin
    
    return count if amount == 0 else -1

2. Essential Data Structures

Learning by Priority

PriorityData StructureFrequencyDifficulty
1ArrayVery HighEasy
2HashMapVery HighEasy
3StackHighEasy
4QueueHighEasy
5HeapMediumMedium
6TreeMediumMedium
7GraphMediumHard

Core Operations by Data Structure

Array:

# Essential operations
arr = [1, 2, 3, 4, 5]
arr.append(6)        # Add at end O(1)
arr.pop()            # Remove from end O(1)
arr.insert(0, 0)     # Add at front O(n)
arr.remove(3)        # Remove value O(n)
arr.sort()           # Sort O(n log n)

HashMap:

# Essential operations
d = {}
d['key'] = 'value'   # Insert O(1)
val = d.get('key')   # Lookup O(1)
del d['key']         # Delete O(1)
'key' in d           # Check existence O(1)

Stack:

# Stack (LIFO)
stack = []
stack.append(1)      # push
stack.append(2)
top = stack.pop()    # pop (2)

Queue:

# 필요한 모듈 import
from collections import deque
# Queue (FIFO)
queue = deque()
queue.append(1)      # enqueue
queue.append(2)
front = queue.popleft()  # dequeue (1)

Heap:

import heapq
# Min heap
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
min_val = heapq.heappop(heap)  # 1
# Max heap (use negative)
max_heap = []
heapq.heappush(max_heap, -3)
heapq.heappush(max_heap, -1)
max_val = -heapq.heappop(max_heap)  # 3

3. Problem-Solving Patterns

Pattern Recognition Flowchart

flowchart TD
    A[Read Problem] --> B{Sorted Array?}
    B -->|Yes| C[Binary Search or Two Pointers]
    B -->|No| D{Subarray/Substring?}
    D -->|Yes| E[Sliding Window]
    D -->|No| F{Graph/Tree?}
    F -->|Yes| G[BFS/DFS]
    F -->|No| H{Optimization Problem?}
    H -->|Yes| I[DP or Greedy]
    H -->|No| J[HashMap or Stack/Queue]

Examples by Pattern

Pattern 1: Two Pointers

# LeetCode 15. 3Sum
def three_sum(nums):
    nums.sort()
    result = []
    
    for i in range(len(nums) - 2):
        if i > 0 and nums[i] == nums[i-1]:
            continue
        
        left, right = i + 1, len(nums) - 1
        while left < right:
            total = nums[i] + nums[left] + nums[right]
            if total == 0:
                result.append([nums[i], nums[left], nums[right]])
                left += 1
                right -= 1
                while left < right and nums[left] == nums[left-1]:
                    left += 1
            elif total < 0:
                left += 1
            else:
                right -= 1
    
    return result

Pattern 2: Sliding Window

# LeetCode 3. Longest Substring Without Repeating Characters
def length_of_longest_substring(s):
    char_set = set()
    left = 0
    max_length = 0
    
    for right in range(len(s)):
        while s[right] in char_set:
            char_set.remove(s[left])
            left += 1
        
        char_set.add(s[right])
        max_length = max(max_length, right - left + 1)
    
    return max_length

Pattern 3: BFS

# LeetCode 102. Binary Tree Level Order Traversal
from collections import deque
def level_order(root):
    if not root:
        return []
    
    result = []
    queue = deque([root])
    
    while queue:
        level_size = len(queue)
        level = []
        
        for _ in range(level_size):
            node = queue.popleft()
            level.append(node.val)
            
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        
        result.append(level)
    
    return result

Pattern 4: Dynamic Programming

# LeetCode 70. Climbing Stairs
def climb_stairs(n):
    if n <= 2:
        return n
    
    dp = [0] * (n + 1)
    dp[1], dp[2] = 1, 2
    
    for i in range(3, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    
    return dp[n]

4. Time Management

Exam Time Allocation (2 hours, 4 problems)

Total time: 120 minutes
Problem 1 (Easy):   20 minutes
Problem 2 (Medium): 30 minutes
Problem 3 (Medium): 35 minutes
Problem 4 (Hard):   35 minutes
Buffer time: 10 minutes (review and debugging)

Problem-Solving Process

flowchart LR
    A[Read Problem 3min] --> B[Analyze Examples 2min]
    B --> C[Design Approach 5min]
    C --> D[Write Code 15min]
    D --> E[Test 3min]
    E --> F[Debug 2min]

Checklist for Each Stage: 1. Read Problem (3 min):

  • Check input format
  • Check output format
  • Check constraints (n range, time limit)
  • Identify edge cases 2. Analyze Examples (2 min):
  • Trace example input/output by hand
  • Pattern recognition
  • Think about exception cases 3. Design Approach (5 min):
  • Calculate brute force time complexity
  • Consider optimization methods
  • Select data structures
  • Write pseudocode 4. Write Code (15 min):
  • Write function signature
  • Implement core logic
  • Handle edge cases 5. Test (3 min):
  • Test with example inputs
  • Test edge cases (empty array, size 1, max size)
  • Check output format 6. Debug (2 min):
  • Check error messages
  • Print debugging
  • Fix logic errors

5. Language Selection

Pros and Cons by Language

LanguageProsConsRecommended For
PythonConcise syntax, fast implementationSlow speed (TLE possible)Most cases
C++Fast speed, STLLong code, debugging difficultyPerformance-critical problems
JavaStable, rich APIVerbose syntaxEnterprise background
JavaScriptFamiliar to web developersLack of type safetyWeb developers

1. Concise Syntax:

# Python (5 lines)
def reverse_string(s):
    return s[::-1]
# C++ (10 lines)
#include <string>
#include <algorithm>
string reverseString(string s) {
    reverse(s.begin(), s.end());
    return s;
}

2. Rich Built-in Functions:

# Sorting
arr.sort()
# Max/Min
max_val = max(arr)
min_val = min(arr)
# Sum
total = sum(arr)
# Count
from collections import Counter
count = Counter(arr)

3. Slicing:

arr = [1, 2, 3, 4, 5]
arr[1:4]    # [2, 3, 4]
arr[::-1]   # [5, 4, 3, 2, 1] (reverse)
arr[::2]    # [1, 3, 5] (every 2)

When to Use C++

When TLE (Time Limit Exceeded) Occurs:

Problem constraint: n ≤ 10^6, time limit 1 second
Python: 10^6 operations → 1 second (tight)
C++:    10^6 operations → 0.1 second (comfortable)
→ Switch to C++ if Python gets TLE

C++ STL Essentials:

#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
// Vector
vector<int> v = {1, 2, 3};
v.push_back(4);
// Sort
sort(v.begin(), v.end());
// Binary search
bool found = binary_search(v.begin(), v.end(), 3);
// Priority queue (max heap)
priority_queue<int> pq;
pq.push(3);
int top = pq.top();

6. Practical Tips

Tip 1: Prepare Templates

Python Template:

# Input processing
n = int(input())
arr = list(map(int, input().split()))
# Or
import sys
input = sys.stdin.readline
# Output
print(result)

C++ Template:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    cin >> n;
    
    vector<int> arr(n);
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    
    // Logic
    
    cout << result << endl;
    
    return 0;
}

Tip 2: Time Complexity Check

Estimate time complexity from n range:
n ≤ 10:        O(n!) possible
n ≤ 20:        O(2^n) possible
n ≤ 100:       O(n³) possible
n ≤ 1,000:     O(n²) possible
n ≤ 10,000:    O(n² / 2) possible
n ≤ 100,000:   O(n log n) needed
n ≤ 1,000,000: O(n) needed
n > 1,000,000: O(log n) or O(1) needed

Tip 3: Debugging Strategy

# Print debugging
def solve(arr):
    print(f"DEBUG: arr = {arr}")  # Check input
    
    result = []
    for i in range(len(arr)):
        print(f"DEBUG: i = {i}, arr[i] = {arr[i]}")  # Check process
        result.append(arr[i] * 2)
    
    print(f"DEBUG: result = {result}")  # Check output
    return result

Tip 4: Edge Case Check

# Cases to always test
test_cases = [
    [],              # Empty array
    [1],             # Size 1
    [1, 1, 1],       # All same values
    [1, 2, 3],       # Sorted array
    [3, 2, 1],       # Reverse order
    [-1, 0, 1],      # Contains negative
    [10**9],         # Max value
]

Tip 5: Common Mistakes to Avoid

1. Off-by-one errors:

# ❌ Wrong
for i in range(len(arr) - 1):  # Misses last element
# ✅ Correct
for i in range(len(arr)):

2. Integer overflow:

# Python: No overflow (arbitrary precision)
# C++: Use long long for large numbers
long long result = (long long)a * b;

3. Modifying while iterating:

# ❌ Wrong
for item in arr:
    if condition:
        arr.remove(item)  # Modifies during iteration
# ✅ Correct
arr = [item for item in arr if not condition]

7. Summary

3-Month Study Plan

Month 1: Build Foundation

  • Array, HashMap, Stack, Queue
  • Two Pointers, Sliding Window
  • LeetCode Easy 50 problems Month 2: Intermediate Algorithms
  • BFS/DFS, Binary Search
  • Dynamic Programming basics
  • LeetCode Medium 50 problems Month 3: Advanced Algorithms
  • Advanced Dynamic Programming
  • Graph algorithms
  • LeetCode Medium 50 + Hard 20 problems

Study Resources

Online Judges:

  • LeetCode - Global standard
  • HackerRank - Interview prep
  • Codeforces - Competitive programming Recommended Problem Sets:
  • LeetCode Top 100 Liked
  • LeetCode Blind 75
  • NeetCode 150

Next Steps

For detailed algorithm explanations, refer to these series:

Quick Study Guide

Week 1-2: Arrays, HashMap basics
Week 3-4: Two Pointers, Sliding Window
Week 5-6: Stack, Queue, BFS/DFS
Week 7-8: Binary Search, Sorting
Week 9-10: Dynamic Programming basics
Week 11-12: Advanced DP, Greedy, Backtracking

Practice Schedule

Daily routine (2-3 hours):
1. Review 1 concept (30 min)
2. Solve 2 new problems (60 min)
3. Review 1 past problem (30 min)
Weekly:
- Monday-Friday: New problems
- Saturday: Mock test (4 problems, 2 hours)
- Sunday: Review wrong answers

Keywords

Coding Test, Algorithm, Data Structure, LeetCode, Interview, Two Pointers, Sliding Window, BFS, DFS, Dynamic Programming, Binary Search, Python, C++


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. Systematically organize coding test preparation strategy.

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers Coding Test, Algorithm, Data Structure, LeetCode, Interview, Programming.