C++ Algorithms | "Must-Solve" Problems for Coding Tests
이 글의 핵심
Interview-style C++ patterns: binary search on answer, two pointers, heaps, DP—complexity notes and when to trust std:: algorithms.
These snippets are interview-style patterns you can drop into competitive programming or coding tests. Prefer std:: algorithms (lower_bound, sort, priority_queue) when they clarify intent and avoid off-by-one bugs; use raw loops when the problem is tiny or needs a very specific traversal. Each snippet notes typical time/space complexity—always re-check constraints (n, value ranges) before choosing O(n²) vs O(n log n) vs O(n).
1. Two Sum
Problem: Find the indices of two numbers in an array that add up to the target.
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> seen;
for (int i = 0; i < nums.size(); i++) {
int complement = target - nums[i];
if (seen.find(complement) != seen.end()) {
return {seen[complement], i};
}
seen[nums[i]] = i;
}
return {};
}
// Time Complexity: O(n)
// Space Complexity: O(n)
2. Binary Search
Problem: Find the target in a sorted array.
int binarySearch(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
// Time Complexity: O(log n)
3. Maximum Subarray
Problem: Find the maximum sum of a contiguous subarray.
int maxSubArray(vector<int>& nums) {
int maxSum = nums[0];
int currentSum = nums[0];
for (int i = 1; i < nums.size(); i++) {
currentSum = max(nums[i], currentSum + nums[i]);
maxSum = max(maxSum, currentSum);
}
return maxSum;
}
// Kadane's Algorithm
// Time Complexity: O(n)
4. Coin Change
Problem: Find the minimum number of coins needed to make up the given amount.
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (i >= coin) {
dp[i] = min(dp[i], dp[i - coin] + 1);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
// Dynamic Programming
// Time Complexity: O(amount * coins.size())
5. Number of Islands
Problem: Count the number of islands in a 2D grid.
class Solution {
private:
void dfs(vector<vector<char>>& grid, int i, int j) {
if (i < 0 || i >= grid.size() ||
j < 0 || j >= grid[0].size() ||
grid[i][j] == '0') {
return;
}
grid[i][j] = '0'; // Mark as visited
dfs(grid, i + 1, j);
dfs(grid, i - 1, j);
dfs(grid, i, j + 1);
dfs(grid, i, j - 1);
}
public:
int numIslands(vector<vector<char>>& grid) {
int count = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == '1') {
count++;
dfs(grid, i, j);
}
}
}
return count;
}
};
// DFS
// Time Complexity: O(m * n)
6. Valid Parentheses
Problem: Check if a string of parentheses is valid.
bool isValid(string s) {
stack<char> st;
unordered_map<char, char> pairs = {
{')', '('},
{'}', '{'},
{']', '['}
};
for (char c : s) {
if (pairs.find(c) == pairs.end()) {
// Opening parenthesis
st.push(c);
} else {
// Closing parenthesis
if (st.empty() || st.top() != pairs[c]) {
return false;
}
st.pop();
}
}
return st.empty();
}
// Time Complexity: O(n)
7. Longest Increasing Subsequence (LIS)
Problem: Find the length of the longest increasing subsequence.
int lengthOfLIS(vector<int>& nums) {
vector<int> dp(nums.size(), 1);
int maxLen = 1;
for (int i = 1; i < nums.size(); i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
maxLen = max(maxLen, dp[i]);
}
return maxLen;
}
// Dynamic Programming
// Time Complexity: O(n²)
// Optimized Version (Binary Search)
int lengthOfLIS_optimized(vector<int>& nums) {
vector<int> tails;
for (int num : nums) {
auto it = lower_bound(tails.begin(), tails.end(), num);
if (it == tails.end()) {
tails.push_back(num);
} else {
*it = num;
}
}
return tails.size();
}
// Time Complexity: O(n log n)
8. 0/1 Knapsack
Problem: Find the maximum value within the weight limit W.
int knapsack(vector<int>& weights, vector<int>& values, int W) {
int n = weights.size();
vector<vector<int>> dp(n + 1, vector<int>(W + 1, 0));
for (int i = 1; i <= n; i++) {
for (int w = 1; w <= W; w++) {
if (weights[i-1] <= w) {
dp[i][w] = max(
dp[i-1][w],
dp[i-1][w - weights[i-1]] + values[i-1]
);
} else {
dp[i][w] = dp[i-1][w];
}
}
}
return dp[n][W];
}
// Time Complexity: O(n * W)
9. Shortest Path (Dijkstra)
Problem: Find the shortest distance from the start node to all other nodes.
vector<int> dijkstra(vector<vector<pair<int,int>>>& graph, int start) {
int n = graph.size();
vector<int> dist(n, INT_MAX);
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;
dist[start] = 0;
pq.push({0, start});
while (!pq.empty()) {
auto [d, u] = pq.top();
pq.pop();
if (d > dist[u]) continue;
for (auto [v, weight] : graph[u]) {
if (dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
pq.push({dist[v], v});
}
}
}
return dist;
}
// Time Complexity: O((V + E) log V)
10. Permutations/Combinations
Problem: Generate all permutations.
void permute(vector<int>& nums, int start, vector<vector<int>>& result) {
if (start == nums.size()) {
result.push_back(nums);
return;
}
for (int i = start; i < nums.size(); i++) {
swap(nums[start], nums[i]);
permute(nums, start + 1, result);
swap(nums[start], nums[i]); // Backtracking
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
permute(nums, 0, result);
return result;
}
// Time Complexity: O(n!)
// Combinations
void combine(int n, int k, int start, vector<int>& current,
vector<vector<int>>& result) {
if (current.size() == k) {
result.push_back(current);
return;
}
for (int i = start; i <= n; i++) {
current.push_back(i);
combine(n, k, i + 1, current, result);
current.pop_back();
}
}
Coding Test Tips
1. Input/Output Optimization
// Fast I/O
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
// File I/O
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
2. Frequently Used Templates
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define vi vector<int>
#define vll vector<long long>
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
// Code...
return 0;
}
3. Debugging Macros
#ifdef LOCAL
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif
int main() {
int x = 10;
debug(x); // Prints only in local environment
}
Common Mistakes
Mistake 1: Integer Overflow
// ❌ Overflow
int sum = a * b;
// ✅ Use long long
long long sum = (long long)a * b;
Mistake 2: Array Out-of-Bounds
// ❌ No boundary check
if (grid[i+1][j] == 1) { ... }
// ✅ Add boundary check
if (i+1 < n && grid[i+1][j] == 1) { ... }
Mistake 3: Time Limit Exceeded
// ❌ O(n³)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
// ✅ Optimize to O(n²) or O(n log n)
FAQ
Q1: Which algorithms should I learn first?
A:
- Sorting, Searching
- Greedy, DP
- Graphs (BFS, DFS)
- Advanced (e.g., Segment Trees)
Q2: What if I can’t solve a problem?
A:
- Start with small examples
- Think brute force first
- Look for patterns
- Find similar problems
Q3: How do I calculate time complexity?
A:
- Single loop: O(n)
- Nested loops: O(n²)
- Binary search: O(log n)
- Sorting: O(n log n)
Q4: Recommended problem-solving platforms?
A:
- LeetCode (English)
- Baekjoon (Korean)
- Programmers (Korean)
- Codeforces (English)
Q5: How long should I prepare for coding tests?
A:
- Beginner: 1-2 months
- Intermediate: 3-6 months
- Advanced: 6+ months
Q6: Is STL necessary?
A: Yes, understanding vector, map, set, and algorithm functions is essential.
Related Posts
Here are some related posts you might find helpful:
- C++ STL algorithms — English series hub
- C++ Coding Test Tips | “10 Proven Strategies for Success”
- C++ Coding Test | “STL Usage by Algorithm Type”
- C++ Algorithms | “Essential STL Algorithm Guide”
Practical Tips
Debugging Tips
- Check compiler warnings first when issues arise
- Reproduce the problem with simple test cases
Performance Tips
- Don’t optimize without profiling
- Set measurable performance goals first
Code Review Tips
- Check for common feedback points in advance
- Follow team coding conventions
Practical Checklist
Use this checklist to ensure quality and avoid mistakes when applying these concepts.
Before Writing Code
- Is this the best approach for solving the problem?
- Will your team understand and maintain this code?
- Does it meet performance requirements?
While Writing Code
- Have you resolved all compiler warnings?
- Have you considered edge cases?
- Is error handling appropriate?
During Code Review
- Is the intent of the code clear?
- Are there sufficient test cases?
- Is the documentation complete?
Use this checklist to reduce errors and improve code quality.
Keywords Covered in This Post
Search for terms like C++, Algorithms, Coding Test, Problem Solving, and PS to find more resources related to this post.