Ch5. DFS/BFS

1. 꼭 필요한 자료구조 기초

    - '탐색'
      : 많은 양의 데이터 중 원하는 데이터를 찾는 과정으로 대표적인 알고리즘으로 DFS, BFS가 있다.

    - '자료구조'

      : 데이터를 표현하고 관리하고 처리하기 위한 구조

        - 오버플로(overflow) : 특정한 자료구조에 수용할 수 있는 데이터가 가득 찬 상태에서 삽입 연산을 수행할 때 발생

        - 언더플로(underflow) : 특정한 자료구조에 데이터가 전혀 들어 있지 않은 상태에서 삭제 연산을 수행할 깨 발생

    1-1. 스택

          - 선입후출 FILO or 후입선출 LIFO 구조

    1-2. 큐

          - FIFO 구조

          - deque 자료구조를 활용하자. 스택과 큐의 장점을 모두 채택한 것인데 데이터를 넣고 빼는 속도가 리스트 자료형에

            비해 효율적이고 queue 라이브러리를 사용하는 것보다 더 간단하다.

    1-3. 재귀 함수

          - 자기 자신을 다시 호출하는 함수

          - 보통 파이썬 인터프리터는 호출 횟수 제한이 있다.

          - '재귀 함수의 종료 조건'이 꼭 필요하다.

          - 내부적으로 스택 자료구조와 동일하다. 따라서 스택 자료구조를 사용해야 하는 많은 알고리즘은 재귀 함수를 이용하여
            간편하게 구현될 수 있다.

          - 재귀함수가 수학의 점화식(재귀식)을 그대로 옮겼기 때문에 재귀 함수의 코드가 더 간결하다.

            * 수학의 점화식 : 특정한 함수를 자신보다 더 작은 변수에 대한 함수와의 관계로 표현한 것을 의미한다.

 

2. 탐색 알고리즘 DFS/BFS

    2-1. DFS

          - 깊이 우선 탐색이라고 부르며, 그래프에서 깊은 부분을 우선적으로 탐색하는 알고리즘이다.

          - 스택을 이용하는 알고리즘이기 때문에 실제 구현은 재귀 함수를 이용했을 때 매우 간결하게 구현할 수 있다.

          - '그래프'
            : 프로그래밍에서 크게 2가지 방식으로 표현할 수 있는데 1) 인접 행렬, 2) 인접 리스트이다.

              1) 인접 행렬(Adjacency Matrix) :  2차원 배열로 그래프의 연결 관계를 표현하는 방식

                 - 연결이 되어 있지 않은 노드끼리는 비용이 무한으로 999999999 등의 큰 값으로 초기화한다.

              2) 인접 리스트(Adjacency List) : list로 그래프의 연결 관계를 표현하는 방식
                 - 모든 노드에 연결된 노드에 대한 정보를 차례대로 연결하여 저장한다.

              3)인접 행렬 vs 인접 리스트

                 : 메모리 측면에서는 인접 행렬이 낭비되고, 속도 측면에서는 인접 리스트가 느리다.

 

    2-2. BFS

          - 너비 우선 탐색이라고 부르며, 가까운 노드부터 탐색하는 알고리즘이다.

          - 큐를 이용하면 선입선출이 되기에 자연스럽게 가까운 노드부터 탐색을 할 수 있다.

 

    2-3. DFS vs BFS
          - 둘 다 탐색을 수행하는데 O(N)의 시간이 소요된다. 컴퓨터 시스템의 특성상 DFS보다 BFS가 좀 빠르다.

 

3. 음료수 얼려 먹기

   - 문제

   - 문제 해결

     : 0인 지점에서 주변 상하좌우를 DFS로 방문하면 된다.

 

   - 소스 코드

더보기

15 14
00000111100000
11111101111110
11011101101110
11011101100000
11011111111111
11011111111100
11000000011111
01111111111111
00000000011111
01111111111000
00011111111000
11111111110011
11100011111111
11100011111111
11111111111111

n, m = map(int, input().split())

ice_box = []
for i in range(n):
  ice_box.append(list(map(int,input())))

def dfs(x, y):
  if x <= -1 or x >= n or y <= -1 or y >= m:
    return False
  
  if ice_box[x][y] == 0:
    ice_box[x][y] = 1
    dfs(x-1,y)
    dfs(x,y+1)
    dfs(x+1,y)
    dfs(x,y-1)
    return True
  return False

result = 0
for i in range(n):
  for j in range(m):
    if dfs(i,j) == True:
      result += 1

print(result)
#include <stdio.h>
using namespace std;

int N, M;
int ice_box[1000][1000];

bool dfs(int x, int y){
	if(x <= -1 || x >= N || y <= -1 || y >= M)
		return false;
	if(ice_box[x][y] == 0){
		ice_box[x][y] = 1;
		dfs(x - 1, y);
		dfs(x, y + 1);
		dfs(x + 1, y);
		dfs(x, y - 1);
		return true;
	}
	return false;
}

int main() {
    scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++)
			scanf("%1d", &ice_box[i][j]);
	}
	int result = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if(dfs(i,j) == true)
				result += 1;
		}
	}
	printf("%d\n", result);
    return 0;
}

 

4. 미로 탈출

   - 문제

   - 문제 해결

     : 시작 지점에서 가장 가까운 노드를 차례대로 탐색하는 BFS로 풀면 된다.

 

   - 소스 코드

더보기

5 6
101010
111111
000001
111111
111111

from collections import deque

n, m = map(int, input().split())
miro = []
for i in range(n):
  miro.append(list(map(int, input())))

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

def bfs(x,y):
  que = deque()
  que.append((x,y))
  
  while que:
    x, y = que.popleft()
    for i in range(4):
      nx = x + dx[i]
      ny = y + dy[i]

      if nx < 0 or nx >= n or ny < 0 or ny >= m:
        continue
      if miro[nx][ny] == 0: continue
      elif miro[nx][ny] == 1:
        miro[nx][ny] = miro[x][y] + 1
        que.append((nx,ny))
  return miro[n-1][m-1]

print(bfs(0,0))
#include <stdio.h>
#include <queue>
using namespace std;

int N, M;
int miro[201][201];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

int bfs(int x, int y){
	queue<pair<int, int>> que;
	que.push({x, y});

	while(!que.empty()){
		int x = que.front().first;
		int y = que.front().second;
		que.pop();

		for (int i = 0; i < 4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
			if(miro[nx][ny] == 0) continue;
			if(miro[nx][ny] == 1) {
				miro[nx][ny] = miro[x][y] + 1;
				que.push({nx, ny});
			}
		}
	}
	return miro[N-1][M-1];
}

int main() {
    scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++)
			scanf("%1d", &miro[i][j]);
	}
	printf("%d\n", bfs(0,0));
    return 0;
}

 

Ch4. 구현 implementation

1. 아이디어를 코드로 바꾸는 구현

      1-1. 피지컬로 승부하기

             - '코딩 테스트에서 구현이란?'

                : 머릿 속에 있는 알고리즘을 소스코드로 바꾸는 과정이다. 모든 범위의 코딩 테스트 문제 유형을 포함하는 개념이다.
                  그렇기 때문에 대부분 구현을 별도의 유형으로 다루지 않지만, 코딩 테스트에서는 자주 출제가 된다.

             - '피지컬이 좋다'
               : 프로그래밍 문법을 정확하게 숙지하고, 라이브러리 사용 경험이 풍부하며, 코드 작성 속도(타자)가 빠를 때 

             - '구현 유형의 문제'
               : 풀이를 떠올리는 것은 쉽지만, 소스코드로 옮기기 어려운 문제
                 (알고리즘은 설계했는데 구현이 먼저 풀 수 있는 문제가 없을 때 푸는 것이 좋다
)

                  1) 완전 탐색: 모든 경우의 수를 주저 없이 다 계산하는 해결 방법

                  2) 시뮬레이션: 문제에서 제시한 알고리즘을 한 단계씩 차례대로 직접 수행해야하는 문제 유형             

              

      1-2. 구현 시 고려해야 할 메모리 제약 사항

             - '변수의 표현 범위'

                1) C/C++/Java
                    : int형, long long형, BigInteger 순으로 자료형의 표현 범위에 주의해야한다.

                2) Python
                    :  직접 자료형을 지정할 필요가 없고 매우 큰 수의 연산 또한 지원하므로 주의하지 않아도 된다.

             - '파이썬에서 리스트 크기'

                 : 파이썬에서 리스트를 이용할 때 코딩 테스트의 메모리 제한을 고려해야 한다. (그러나, 드물다)

 

      1-3. 채점 환경

             - 시간 제한이 1초이고, 데이터의 개수가 100만개인 문제가 있다면 일반적으로 시간 복잡도 O(NlogN)이내의

               알고리즘을 이용하여 풀어야 한다. N = 1,000,000(100만) -> NlogN = 약 20,000,000(2000만번)

               (제출한 코드가 1초에 2000만번의 연산을 수행한다고 가정하면 크게 무리가 없다)

             - 따라서 알고리즘 문제를 풀 때는 시간 제한과 데이터의 개수를 먼저 확인한 뒤 이 문제를 어느 정도의 시간 복잡도의

               알고리즘으로 작성해야 풀 수 있을 것인지 예측할 수 있어야 한다.

               

      1-4. 구현 문제에 접근하는 방법

             - 특징
               1) 문제의 길이가 길지만, 고차원적인 사고력을 요구하지 않기 때문에 문법에 익숙하다면 오히려 쉽게 풀 수 있다.

               2) 문자열을 처리하거나 큰 정수를 처리하는 구현 문제가 나올 때는 C/C++/Java보다 Python이 쉬울 수 있다.

              

      1-5. 상하좌우

             - 문제

             - 문제 해결
                : 요구사항대로 구현하면 연산 횟수는 이동 횟수에 비례하게 된다. 이동 횟수가 N번인 경우 시간 복잡도 O(N)이다.
                  일련의 명령에 따라 개체를 차례대로 이동시킨다는 점에서 simulation 유형으로 분류되며 구현이 중요한 문제다.

             - 소스 코드

 

      1-6. 시각

             - 문제

             - 문제 해결

               : 00시 00분 00초 ~ 23시 59분 59초까지의 모든 경우의 수는 86,400가지(24*60*60초)이다.

                 경우의 수가 100,000가지도 되지 않기 때문에 시간 제한 2초 안에 문제를 해결할 수 있다.

                 가능한 경우의 수를 모두 검사하는 방법으로 완전 탐색 유형이다.

                 일반적으로 탐색해야할 전체 데이터의 개수가 100만개 이하일 때 완전 탐색을 사용하면 적절하다.

             - 소스 코드

 

2. 왕실의 나이트

    - 문제

    - 문제 해결

       : 나이트가 위치한 곳을 문자열과 숫자의 조합이 아니라 같은 행과 열 형태로 들어올 수도 있었다. (예외처리 필요)

         이 문제는 나이트가 이동할 수 있는 경로를 하나씩 확인하여 이동하면서 결과를 확인하면 된다. 

         나이트가 이동할 수 있는 경로는 2가지이다.

          1) 수평으로 두 칸 이동 후 수직으로 한 칸 이동

          2) 수직으로 두 칸 이동 후 수평으로 한 칸 이동

가능한 움직임을 (x,y) 나타내면 (-1, -2), (1, -2), (-1, 2), (1, 2), (-2, -1), (2, -1), (-2, 1), (2, 1)로 8가지의 경우가 나온다.

 

상하좌우와 비슷한 문제지만 이동방향을 dx,dy를 사용하느냐,
특정 방향 값을 지정하여 방향을 설정하느냐 2가지 모두 자주 사용되므로 참고!

 

 

    - 소스 코드

 

3. 게임 개발

    - 문제 

    - 문제 해결

      :  문제가 길고 문제를 바르게 이해하여 소스 코드로 옮기는 과정이 간단하지 않기 때문에 반복적인 숙달이 필요하다.

    - 소스 코드

n, m = map(int, input().split())
visit = [[0] * m for _ in range(n)]

x, y, direction = map(int, input().split())
visit[x][y] = 1

arr = []
for i in range(n):
  arr.append(list(map(int, input().split())))

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

def turn_left():
  global direction
  direction -= 1
  if direction == -1:
    direction = 3

count = 1;
turn_time = 0
while True:
  turn_left()
  nx = x + dx[direction]
  ny = y + dy[direction]

  if visit[nx][ny] == 0 and arr[nx][ny] == 0:
    visit[nx][ny] = 1
    x = nx
    y = ny
    count += 1
    turn_time = 0
    continue
  else:
    turn_time += 1
  
  if turn_time == 4:
    nx = x - dx[direction]
    ny = y - dy[direction]
    if arr[nx][ny] == 0:
      x = nx
      y = ny
    else:
      break
    turn_time = 0

print(count)
#include <stdio.h>
using namespace std;

int N, M, x, y, dir;
int dx[4] = { -1, 0, 1, 0 };
int dy[4] = { 0, 1, 0, -1 };
int arr[51][51];
int visit[51][51];

void turn_left() {
    dir -= 1;
    if (dir == -1) dir = 3;
}

int main() {
    scanf("%d %d", &N, &M);
    scanf("%d %d %d", &x, &y, &dir);
    visit[x][y] = 1;

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++)
            scanf("%d", &arr[i][j]);
    }
    int count = 1;
    int turn_cnt = 0;
    while (true) {
        turn_left();
        int nx = x + dx[dir];
        int ny = y + dy[dir];
        if (visit[nx][ny] == 0 && arr[nx][ny] == 0) {
            visit[nx][ny] = 1;
            x = nx; y = ny;
            count += 1; turn_cnt = 0;
            continue;
        }
        else turn_cnt += 1;

        if (turn_cnt == 4) {
            nx = x - dx[dir];
            ny = y - dy[dir];
            if (arr[nx][ny] == 0) {
                x = nx; y = ny;
            }
            else break;
            turn_cnt = 0;
        }
    }

    printf("%d", count);
    return 0;
}

Ch3. 그리디 greedy

1. 당장 좋은 것만 선택하는 그리디

    - 현재 상황에서 당장 좋은 것만을 골라 현재의 선택이 나중에 미칠 영향은 고려하지 않는 방법

    - 보통 코딩 테스트에서 출제되는 유형은 창의력, 즉 문제를 풀기 위한 최소한의 아이디어를 떠올릴 수 있는 능력을 요구한다.

      특정한 문제를 만났을 때, 그리디로 문제를 풀 수 있을지 파악할 수 있어야 한다.

   - 기준에 따라 좋은 것을 선택하는 알고리즘이기에 기준을 제시해주고, 정렬 알고리즘과 함께 짝을 이루어 출제된다.

      1-1. 예제 거스름돈

             - 문제

             - 소스 코드

             - 정당성
               : 가지고 있는 동전 중에서 큰 단위가 항상 작은 단위의 배수이므로 작은 단위의 동전들을 조합해 다른 해가 나올 수 X
 

                 때문에 화폐이 단위가 무작위로 주어졌을 때에 그리디 알고리즘으로 해결할 수 없다.

    

      1-2. 그리디 알고리즘의 정당성

             - 대부분의 문제는 그리디 알고리즘을 이용했을 때 '최적의 해'를 찾을 수 없는 가능성이 다분하다.

               따라서, 그리디 알고리즘으로 문제의 해법을 찾았을 때는 그 해법이 정당한지 검토할 수 있어야 한다.

               Tip. 그리디 -> 다이나믹, 그래프 알고리즘

 

2. 큰 수의 법칙

    - 문제

    - 문제 해결

       : 가장 큰 수와 두번째로 큰 수를 저장한다. 연속으로 더할 수 있는 횟수는 최대 K번이므로

         '가장 큰 수를 K번 더하고, 두 번째로 큰수를 한 번 더하는 연산'을 반복하면 된다.

    - 소스 코드 1(python, M이 10,000 이하일 때)

    - 소스 코드 2(python, M이 100억 이상일 때)

       : 반복되는 수열 first와 second가 더해질 때 특정한 수열 형태로 일정하게 반복해서 더해지는 특징이 있다.

         반복되는 수열의 길이는 (K+1)이고 M을 (K+1)로 나눈 몫이 수열이 반복되는 횟수가 된다.
         여기에 (K+1)*M은 first가 반복하는 횟수가 되고, M이 (K+1)로 나누어 떨어지지 않는 것을 고려했을 때,

         '가장 큰 수가 더해지는 횟수는 int(M/(K+1)) * K + M%(K+1)'

    - 소스 코드 3(c++, M이 100억 이상일 때)

 

3. 숫자 카드 게임

    - 문제

    - 문제 해결

       : 각 행마다 가장 작은 수를 찾은 뒤에 작은 수들 중에서 가장 큰 수를 찾는 것이다.

    - 소스 코드

 

4. 1이 될 때까지

    - 문제

    - 문제 해결

       : 주어진 n에 대하여 최대한 많이 나누기 연산을 수행하면 된다.

    - 소스 코드

Ch2. 코딩 테스트 개요16~20년 코테 기출 유형 분석

1. 최신 출제 경향과 준비 방향

    - IT 직군에서 코딩 테스트를 보는 대표적인 기업은 삼성전자, 카카오, 라인이 있다.

    - 보통 2~5시간 동안 8개 이하의 알고리즘 문제들을 풀도록 한다. (얼마나 정확하고, 빠른 알고리즘인지 순위를 매김)

         1-1. 코딩테스트는 문제 해결 능력을 확인하는 시험

                - 잘못된 편견
                 : 기업에서 주관하는 코딩 테스트는 매우 높은 사고력이나 어려운 알고리즘 기반의 지식을 요구하지 않는다.

                   따라서 코딩 테스트에는 주로 기초 알고리즘에 기반하는 문제가 출제된다.

                - 코딩 테스트 기출 유형 빈도수

                   simulation or BFS/DFS > greedy >> sort or dynamic programming > binary search or shortest path

                   (구현 or BFS/DFS > 그리디 > 정렬 or 다이나믹 > 이진 탐색 or 최단 경로)

 

        1-2. 기업별 문제 출제 경향

               - 카카오는 문자열을 처리하는 구현 문제와 다양한 케이스를 고려해야 안정적으로 만점을 받을 수 있는 문제들이,

                 삼성전자는 문제를 바르게 읽고, 예외 상황을 적절히 처리하는 방식으로 소스코드를 작성해야 하는 문제들이

                 출제되었다.

               - 보통 합격자는 문제의 평균 69%를 풀었으며, 불합격자는 평균 38%의 문제를 풀었다고 한다.

 

2. 연도별 코딩 테스트 유형 분석

   - 알고리즘 대회 수상 경험이 있는 응시자는 삼성전자, 카카오, 라인 모두 합격권에 있다.

     (국제 알고리즘 대회 기준, 코드포스 블루 이상, ACM-IMPC 서울 지역 대회 본선에 안정적으로 진출할 수 있는 수준)

  - 공채를 기준으로 설명하지만, 인턴 채용의 경우에도 비슷한 수준과 유형의 문제로 출제된다.

 

        2-1. 2020년

              - 삼성전자(완전 탐색, 시뮬레이션, DFS/BFS)
                : 완전 탐색 유형에서 시뮬레이션 유형으로 바뀌고 있는 추세이다. 둘 다 요구하는 문제가 출제되고 있으
므로
                  사소한 조건을 고려하면서, 약간 응용된 BFS/DFS 소스 코드를 작성할 수 있는 수준으로 공부하자.

              - 라인(시뮬레이션, 문자열, 자료구조 [4/6])

 

        2-2. 2019년

              - 삼성전자(완전 탐색, 시뮬레이션, DFS/BFS)
                 : 기출문제가 잘 알려져 좋은 성적을 받고 있기 때문에 2문제를 맞혀야 통과할 수 있었다.

              - 카카오(1차:시뮬레이션, 이진 탐색, 자료 구조 중 7문제 [3/7]예상)(2차:추천 시스템 개발 1 문제)

                 : REST API, JSON 등의 원리에 대해 이해하고 있어야 풀 수 있는 개발형 코딩 테스트가 출제되었다. -> 부록 C

              - 라인(상:탐색,시뮬레이션,문자열,다이나믹 프로그래밍 [3/5]예상)(하:자료구조,완전탐색,시뮬레이션 [4/6])

 

        2-3. 2018년

              - 삼성전자(완전 탐색, 시뮬레이션, DFS/BFS)

              - 카카오(1차:시뮬레이션, 그리디, 자료 구조 중 7문제 [3/7]예상)(2차:시뮬레이션 개발 1 문제)

                 : REST API, JSON 등의 원리에 대해 이해하고 있어야 풀 수 있는 개발형 코딩 테스트가 출제되었다. -> 부록 C

              - 라인(상:탐색,시뮬레이션,그리디,다이나믹 프로그래밍 [2/5])(하:그리디,탐색,시뮬레이션,문자열 [2/4]예상)

 

        2-4. 2017년

              - 삼성전자(완전 탐색, 시뮬레이션, DFS/BFS)

              - 카카오(1차:시뮬레이션, 그리디, 문자열 중 7문제 [4/7]예상)(2차:클롤러 개발 1 문제)

                            (3차:시뮬레이션, 그리디, 문자열 중 5문제 [3/5]예상)

                 : REST API, JSON 등의 원리에 대해 이해하고 있어야 풀 수 있는 개발형 코딩 테스트가 출제되었다. -> 부록 C

              - 라인(상:탐색,시뮬레이션,그리디 [3/5])(하:그리디,시뮬레이션,문자열 [2/5]예상)

 

        2-5. 2016년(이하 생략)

 

3. 성공적인 취업을 위한 가이드

    3-1. 채용 프로세스
           : [서류 검토] -> [코딩 테스트] -> [기술 면접] -> [인성 면접]

            3-1.1) 대기업과 스타트업의 채용 프로세스 비교

                   - 대기업은 코딩 테스트에, 스타트업은 기술 면접에 더 비중을 둔다.

            3-1.2) 알고리즘 문제만 잘 풀면 될까?

                   - 알고리즘 외에도 컴퓨터 구조, 운영체제 등 컴퓨터 공학 전반에 대한 다양한 지식에 관해 공부해야 한다.

                   - 인성 면접에 대한 질의 응답도 준비해야 한다.

 

    3-2. 기술 면접의 대표 유형

           : 알고리즘 문제 풀이와 질의응답/ 포트폴리오 질의응답/ 컴퓨터공학 지식 질의응답 유형으로 진행한다.

           : 본질은 업무에서 요구하는 만큼의 컴퓨터 이론 지식을 갖추고 있으며, 필요한 관련 프로젝트에 경험이 있고,

             알고 있는 내용을 논리 정연하게 설명할 수 있으면 된다.

            3-2).1) 알고리즘 문제 풀이와 질의응답 형식

            3-2).2) 포트폴리오 질의응답 형식

            3-2).3) 컴퓨터 공학 지식 질의응답 형식

             // 추후에 p73

 

    3-3. 기술 면접의 준비

           : 기업에서 원하는 직원은 문제를 풀어 정답 판정을 받는 지원자가 아니라, 자신이 어떤 방법으로 문제에 접근하여

             어떠한 알고리즘을 사용했는지를 논리 정연하게 설명할 수 있는 지원자를 원한다.

             -> 평소 기술 블로그나 깃허브 저장소를 운영하며 능력을 키워갈 수 있다.

            3-3).1) 깃허브 사용하기

            3-3).2) 기술 면접의 어려움

            3-3).3) 인성 면접 질문 리스트
                        Q1.

                        Q2.

                        Q3.

 

    3-4. 알고리즘 문제 사이트
           : 외국계 기업에 취업하려는 취업 준비생이나 국제 알고리즘 대회를 준비하는 학생은 아래 사이트를 추천한다.

             (영어 문제를 해석하는 능력 또한 필요하다)

             3-4).1) 코드 시그널

             3-4).2) 코드 포스

             3-4).3) 정올

 

    3-5. 커뮤니티 사이트

             3-4).1) 생활코딩

             3-4).2) BOJ Slack

Ch1. 코딩 테스트 개요

1. 코딩테스트 개념과 배경

    - 온라인 저지 사이트(Online Judge)

      : 프로그래밍 대회나 코딩 테스트에서 나올 법한 문제를 시험해보는 온라인 시스템이다.

          1-1. 코딩테스트의 유형

                1) 온라인 코딩 테스트

                    : 온라인 코딩 테스트는 타인과 문제 풀이를 공유하지 않는 선에서 인터넷 검색을 허용하는 경우가 많지만, 

                      명확한 규정을 안내 사항으로 명시하고 있으니, 규칙과 주의 사항을 반드시 확인해야 한다.

                      온라인 IDE를 이용하는 경우 소스코드가 공개 상태로 온라인에 배포되어 부정행위로 간주될 수 있으므로 주의!!

                      (Ideone과 같은 온라인 IDE 서비스에서 소스 코드 옵션이 public일 경우 구글 등의 검색 엔진에 노출되므로!)


                2) 오프라인 코딩 테스트 

                    : 응시자가 많이 좁혀진 상태이므로 코딩 테스트를 보고 별도의 면접실로 안내되어 화이트보드 혹은 종이와 함께

                      자신이 문제를 해결한 과정 등에 대해서 설명하기도 한다.

 

         1-2. 코딩 테스트 준비를 돕는 다양한 서비스

                1) 코드업

                    : [문제] - [문제집]에서 [기초 100제]를 꼭 풀어보고 백준 온라인 저지로 넘어가기

                2) 백준 온라인 저지

                    : 알고리즘 분류 태그와 난이도를 부여하는 크롬의 확장 프로그램 solved.ac를 설치하기

                      [문제] - [알고리즘 분류]으로 이동하면 유형별 알고리즘을 풀 수 있는데, 책의 진도와 맞게 풀기

                      책을 완독한 이후에 SW 역량 테스트 문제를 풀기

                3) 프로그래머스

                   : 카카오 공채 문제를 모두 제공하는 사이트이다.

                     책을 통해서 기초 개념을 잡고, 추가로 프로그래머스에서 문제를 풀기

                4) SW Expert Academy

                   : 삼성에서 '상시 SW 역량테스트' 제도를 운영하고 있는데, A형을 응모해서 실력을 확인하길 바란다.

 

        1-3. 어떤 언어가 코딩 테스트에 유리할까?

              -  가장 유리한 언어는 Python과 C++이다.

 

2. 실습 환경 구축하기

   - 일반적인 코딩 테스트는 문제마다 소스코드를 1개만 제출하므로 굳이 별도의 개발 환경을 구축하지 않아도 된다.

     따라서 온라인 IDE를 사용하는 게 좋다.

 

        2-1. 온라인 개발 환경

              - 리플릿, 파이썬 튜터, 온라인 GDB이 있다.

나는 온라인 IDE로 리플릿을 선택했다.

 

        2-2. 오프라인 개발 환경

              - 파이참, 주피버 노트북, 비주얼 스튜디오 코드 등이 있다.

혹시 몰라 오프라인으로 파이참을 설치했다.
Run은 되는데..
뭐가 문제인지.. Python console은 안 된다ㅠㅜ 검색을 해도 잘 안 나온다ㅠ

일단 갈 길이 멀기 때문에 이렇게 만족하고 다음 장으로 넘어간다!

 

3. 복잡도

        - 복잡도의 종류

          1) 시간 복잡도: 알고리즘을 위해 필요한 연산의 횟수

          2) 공간 복잡도: 알고리즘을 위해 필요한 메모리의 양

          +) 실제로 메모리를 더 많이 사용해 시간을 비약적으로 줄이는 방법으로 메모이제이션(memorization) 기법이 있는데
              이 내용은 8장에서 다룬다.

 

        3-1. 시간 복잡도

              - 시간 제한이 있다. (1~5초)
                 : 작성한 프로그램이 모든 입력을 받아 이를 처리하고 실행 결과를 출력하는데 걸리는 시간

              - 빅오(Big-O) 표기법을 사용한다.

                 : 가장 빠르게 증가하는 항만을 고려하는 표기법 // 연산의 횟수에 focus

                    - 시간 복잡도는 언제나 최악의 경우를 우선적으로 고려해야 한다. (차수가 작은 항들을 완전히 무시하지 말 것!)

                 [연산]: 프로그래밍 언어에서 지원하는 사칙 연산, 비교 연산 등의 기본 연산을 의미

              - 일반적으로 CPU 기반의 개인 컴퓨터나 채점용 컴퓨터에서는 연산 횟수가 10억을 넘어가면 C 언어를 기준으로
                통상 1초 이상의 시간이 소요된다.

                따라서 능숙한 개발자들은 문제의 조건을 확인한 뒤에 사용할 수 있는 알고리즘을 좁혀 나간다.

 

 

        3-2. 공간 복잡도

              - 메모리 제한이 있다. (128 ~ 512MB)
                 int arr[1000] : 4KB, int arr[1000000] : 4MB, int arr[2000][2000] : 16MB

              - 빅오(Big-O) 표기법을 사용한다.

 

        3-3. 시간과 메모리 측정

              - 파이썬에서는 프로그램 수행과 메모리 사용량을 측정할 수 있다. 자신이 설계한 알고리즘의 성능을 실제로 확인하며

                시간 측정 라이브러리를 사용해보는 습관을 기르는 것이 좋다.

                (ex. 선택 정렬과 기본 정렬 라이브러리 수행 시간 비교 가능)

코딩 테스트를 준비하다가 확실하게 회사의 산업에 따라서 유리한 언어가 있다는 생각이 들었다.

삼성 기출 문제만 열심히 풀던 내가 라인이나 카카오 온라인 코딩 테스트를 접했을 때의 충격이란...!
(문자열만 나오면 C++을 사랑하는 저는 웁니다..ㅠㅜ)

 

그래서 미루고 미루다 Python에 대해서 공부해야겠다는 다짐을 했고, 

이것이 취업을 위한 코딩 테스트다! 라는 책을 보고 python과 추가로 있는 c++ 파일까지 보면서 알고리즘을 뽀개보려고 한다.

(진짜 대학생 때도 한빛미디어에서 나온 책들의 덕을 톡톡히 봤는데 진짜 사랑합니다)

 

책에서 추천하는 단계가 있다.   

1. 초급 단계     

      1) 파이썬 문법 공부(부록 A 이용)

      2) 코드업에서 쉬운 문제부터 200문제 가량 풀기

      3) 유형별 알고리즘 이론(2부)과 기출문제(3부)학습하기

      4) 백준 온라인 저지에서 유형별 문제 5개 이상 풀기

 

   2. 중급 단계

      5) 책 완독 후 백준 온라인 저지에서 삼성 SW 역량테스트 문제집 풀기

      6) 프로그래머스에서 카카오 문제집 풀기

      7) 책의 2부와 3부를 중심으로 주요 알고리즘 유형 복습하기

 

나는 5단계에 있는 삼성 SW 역량테스트 문제를 풀었고, DFS 또는 BFS로 푼 다른 풀이와 좋은 풀이를 공부한 상태이다.
(이것도 차근차근히 올려야하는데.. 이제 깃허브도 알고, 블로그에 기록도 하니까 잘 올려야지!!)
파이썬은 처음 배우는 거니까 1단계부터 빠르게 훑어볼 생각이다ㅎㅎ

 

필자의 직강 동영상을 볼 수 있는 링크이다.

www.youtube.com/playlist?list=PLRx0vPvlEmdBFBFOoK649FlEMouHISo8N

 

필자에게 질문을 남기거나 코드를 볼 수 있는 github이다.

github.com/ndb796

 

현재 책에 나온 부록 A(파이썬 문법 공부)를 한 번 훑었고, 1장부터 공부하러 고고!

 

 

+ Recent posts