책 소개
소스 코드 파일은 여기에서 내려 받으실 수 있습니다.
https://github.com/AcornPublishing/algorithmic-thinking
요약
알고리듬과 데이터 구조를 활용해 컴퓨터 문제를 해결하는 데 초점을 맞춘 책이다. 세계적인 프로그래밍 대회에 출제된 문제들 중 도전적이고 배울 점이 많은 문제를 엄선해 저자만의 알고리듬 설계 방법을 가르친다. 문제 분류, 데이터 구조 선택, 알고리듬 식별뿐만 아니라 해시 테이블, 힙, 트리와 같은 구조의 선택이 실행 시간에 미치는 영향과 최적화 방법도 다룬다. 또한 재귀, 동적 프로그래밍, 이진 탐색과 같은 전략을 통해 도전적인 문제를 해결하는 방법을 소개하며 코드 라인별 분석 및 다양한 알고리듬과 데이터 구조 사용법을 설명한다. 각 문제의 해법은 실제로 프로그래밍 판정 시스템(온라인 저지) 웹 사이트에서 직접 결과를 확인할 수 있다.
추천의 글
처음 테니스를 배울 때는 코트로 넘어온 공을 받아치기가 정말 어렵다. 게다가 백핸드 쪽으로 넘어오면 실수하기 일쑤다. 이후 몇 달 동안 꾸준히 연습을 하고 어느 정도 랠리가 될 정도의 기술이 몸에 익으면, 그 재미에 시간 가는 줄 모르고 빠져든다. 상위 기술인 슬라이스 백핸드, 킥 서브, 드롭 발리 등을 배우게 된다. 어느 정도 기술이 갖춰지면 서브와 발리, 칩 앤 차지, 베이스라인 공략처럼 중요하지만 눈에 보이지 않는 전략을 연구한다. 그리고 상대편 선수에 따라 어떤 기술과 전략이 가장 효과가 있는지를 알아내는 직관력을 계속 키운다. 누구에게나 무조건 통하는 만능 기술은 없다.
프로그래밍도 테니스와 마찬가지다. 코딩을 처음 배울 때는 주어진 문제를 컴퓨터에서 실행시키는 것도 상당히 어렵다. 그러나 초보를 벗어나면 진짜로 문제를 푸는 재미를 느끼게 된다. 문제 풀이를 잘 하려면 어떻게 해야 할까? 프로그래밍 분야도 다른 분야와 마찬가지로 모든 문제를 한 번에 해결해주는 만능 기법은 없다. 그러나 해시 테이블, 검색 트리, 반복, 메모이제이션, 동적 프로그래밍, 그래프 검색 등 유용한 고급 기법과 전략을 언제든 활용할 수 있다. 또한 충분한 훈련을 통해 많은 문제와 알고리듬에 딱 맞는 기법이 무엇인지를 알 수 있다. 즉, 반복 검색을 하거나 최소 연산 알고리듬이 필요하다면, 해시 테이블과 최소 힙으로 속도를 높일 수 있다는 것을 알 수 있다. 어떤 문제를 좀 더 작은 하위 문제로 반복 분할해서 해법을 찾으려면 재귀 기법을 사용하면 되고, 하위 문제가 중복될 때는 메모이제이션으로 속도를 높일 수 있다는 점도 알 수 있다.
테니스든 프로그래밍이든 상위 단계로 가려면 반복 연습과 좋은 선생님이라는 두 가지 요소가 필요한데, 바로 이 책이 그 기회를 제공한다. 이 책은 앞에서 말한 개념을 다루기만 하는 단순한 문제집이 아니다. 경진대회 기출 문제에 꼭 맞는 알고리듬을 찾아내고, 그것을 이용해서 문제를 해결하는 연습법도 제시한다. 부디 행복한 문제 풀이 시간이 되길 바란다.
이 책에서 다루는 내용
◆ 체스 게임을 하는 최적의 방법과 책을 번역하는 최적의 방법을 찾기 위한 너비 우선 검색 알고리듬
◆ 미로를 빠져나갈 수 있는 생쥐의 수 또는 두 위치 사이의 가장 빠른 경로의 수를 결정하는 다익스트라 알고리듬
◆ 소셜 네트워크의 연결 여부 또는 친구 여부를 결정하기 위한 유니온-파인드 데이터 구조
◆ 매장 판촉에서 제공되는 금액을 결정하기 위한 힙 데이터 구조
◆ 눈송이가 고유한지 여부를 확인하거나 사전에서 복합어를 식별하기 위한 해시 테이블 데이터 구조
이 책의 대상 독자
난이도 높은 문제를 해결하는 학습법을 배우려는 모든 프로그래머를 위한 책이다. 이 책을 통해 다양한 데이터 구조와 알고리듬, 문제 풀이에 도움이 되는 유형 및 구현 방법을 배울 수 있다.
이 책의 코드는 전부 C언어로 작성됐으나 C언어의 기초는 다루지는 않는다. 독자가 C/C++에 익숙하다면 바로 시작하는 데 어려움이 없을 것이다. 그 외에 자바나 파이썬 등 다른 언어로 프로그래밍한 경험이 있다면 대부분의 내용은 읽으면서 대략 이해할 수 있을 것이다. 그래도 1장을 시작하기 전에 C언어의 개요를 복습한다면 좀 더 도움이 될 것이다. 특히, 포인터와 동적 메모리 할당에 대해서는 기존의 프로그래밍 경험에 관계없이 숙지해 둘 필요가 있다. 독자에게 추천하는 C언어 책은 K. N. 킹의 『C Programming: A Modern Access, 2nd Edition』(W. W. Norton & Company, 2008)으로, C언어에 익숙한 사람에게도 참고용으로서 유용한 책이다.
목차
목차
- 1장. 해시 테이블
- 문제 1: 고유한 눈송이
- 문제 설명
- 문제 단순화
- 핵심 부분 풀이
- 해법 1: 쌍 비교
- 해법 2: 작업량 줄이기
- 해시 테이블
- 해시 테이블 설계
- 해시 테이블 사용 이유
- 문제 2: 복합어
- 문제 설명
- 복합어 식별
- 해법
- 문제 3: 철자 검사
- 문제 설명
- 해시 테이블 방식의 적합성 판단
- 임시 해법
- 요약
- 참고 사항
- 문제 1: 고유한 눈송이
- 2장. 트리와 재귀
- 문제 1: 할로윈 하울
- 문제 설명
- 이진 트리
- 예제 문제 해결
- 이진 트리 표현
- 모든 사탕 모으기
- 완전히 다른 해법
- 최소 경로 이동
- 입력 받기
- 재귀 사용 이유
- 문제 2: 후손 거리
- 문제 설명
- 입력 받기
- 단일 노드의 후손의 수
- 모든 노드의 후손의 수
- 노드 정렬
- 정보 출력
- main 함수
- 요약
- 참고 사항
- 문제 1: 할로윈 하울
- 3장. 메모이제이션과 동적 프로그래밍
- 문제 1: 버거 마니아
- 문제 설명
- 계획 세우기
- 최적해의 특성
- 해법 1: 재귀
- 해법 2: 메모이제이션
- 해법 3: 동적 프로그래밍
- 메모이제이션과 동적 프로그래밍
- 1단계: 최적해 구조
- 2단계: 재귀 해법
- 3단계: 메모이제이션
- 4단계: 동적 프로그래밍
- 문제 2: 구두쇠
- 문제 설명
- 최적해의 특성
- 해법 1: 재귀
- main 함수
- 해법 2: 메모이제이션
- 문제 3: 하키 라이벌
- 문제 설명
- 라이벌 정보
- 최적해의 특성
- 해법 1: 재귀
- 해법 2: 메모이제이션
- 해법 3: 동적 프로그래밍
- 공간 최적화
- 문제 4: 통과 방법
- 문제 설명
- 해법: 메모이제이션
- 요약
- 참고 사항
- 문제 1: 버거 마니아
- 4장. 그래프 및 너비 우선 탐색
- 문제 1: 나이트 추격
- 문제 설명
- 최적 이동
- 최상의 결과
- 변덕스런 해법
- 시간 최적화
- 그래프와 BFS
- 그래프란?
- 그래프와 트리
- 그래프와 BFS
- 문제 2: 로프 오르기
- 문제 설명
- 해법 1: 동작 찾기
- 해법 2: 리모델링
- 문제 3: 책 번역
- 문제 설명
- 그래프 작성
- BFS 구현
- 총 비용
- 요약
- 참고 사항
- 문제 1: 나이트 추격
- 5장. 가중치 그래프의 최단 경로
- 문제 1: 생쥐 미로
- 문제 설명
- BFS 이동
- 가중치 그래프의 최단 경로
- 그래프 작성
- 다익스트라 알고리즘 구현
- 두 가지 최적화
- 다익스트라 알고리즘
- 다익스트라 알고리즘의 실행 시간
- 음수-가중치 에지
- 문제 2: 할머니 집 찾기
- 문제 설명
- 인접 행렬
- 그래프 작성
- 이상한 경로
- 과제 1: 최단 경로
- 과제 2: 최단 경로 수
- 요약
- 참고 사항
- 문제 1: 생쥐 미로
- 6장. 이진 탐색
- 문제 1: 개미 먹이기
- 문제 설명
- 새로운 형태의 트리 문제
- 입력 받기
- 타당성 시험
- 해법 찾기
- 이진 탐색
- 이진 탐색 실행 시간
- 타당성 결정
- 정렬된 배열 탐색
- 문제2: 강 건너기
- 문제 설명
- 탐욕 알고리즘
- 타당성 시험
- 해법 찾기
- 입력 받기
- 문제 3: 삶의 질
- 문제 설명
- 전체 사각형 정렬
- 이진 탐색
- 타당성 시험
- 좀 더 빠른 타당성 시험
- 문제 4: 동굴 문
- 문제 설명
- 하위 작업 풀이
- 선형 탐색 사용
- 이진 탐색 사용
- 요약
- 참고 사항
- 문제 1: 개미 먹이기
- 7장. 힙과 세그먼트 트리
- 문제 1: 수퍼마켓 판촉 행사
- 문제 설명
- 해법 1: 배열의 최댓값과 최솟값
- 최대-힙
- 최소 힙
- 해법 2: 힙
- 힙
- 두 가지 응용 사례
- 데이터 구조 선택
- 문제 2: 트립 생성
- 문제 설명
- 재귀를 이용한 트립 출력
- 레이블 정렬
- 해법 1: 재귀
- 구간 최대 쿼리
- 세그먼트 트리
- 해법 2: 세그먼트 트리
- 세그먼트 트리
- 문제 3: 두 합
- 문제 설명
- 세그먼트 트리 채우기
- 세그먼트 트리 쿼리
- 세그먼트 트리 업데이트
- main 함수
- 요약
- 참고 사항
- 문제 1: 수퍼마켓 판촉 행사
- 8장. 유니온 파인드
- 문제 1: 소셜 네트워크
- 문제 설명
- 그래프 모델링
- 해법1: BFS
- 유니온 파인드
- 해법 2: 유니온 파인드
- 최적화 1: 크기별 유니온
- 최적화 2: 경로 압축
- 유니온 파인드
- 관계: 세 가지 요구사항
- 유니온 파인드 선택
- 최적화
- 문제 2: 친구와 적
- 문제 설명
- 확장: 적
- main 함수
- 파인드와 유니온
- SetFriends와 SetEnemies
- AreFriends와 AreEnemies
- 문제 3: 서랍 정리
- 문제 설명
- 동등한 서랍
- main 함수
- 파인드와 유니온
- 요약
- 참고 사항
- 문제 1: 소셜 네트워크
- 후기
- 부록 A. 알고리즘 실행 시간
- 제한 시간의 한계
- 빅오 표기법
- 선형 시간
- 상수 시간
- 추가 예제
- 2차 시간
- 이 책의 빅오 표기법
- 부록 B. 추가 자료
- 고유한 눈송이: 암시적 연결 리스트
- 버거 마니아: 해법 재구성
- 나이트 추격: 이동 인코딩
- 다익스트라 알고리즘: 힙 사용
- 생쥐 미로: 힙을 사용한 추적
- 생쥐 미로: 힙을 사용한 구현
- 경로 압축을 압축하기
- 1단계: 삼항 연산자 제거
- 2단계: 할당 연산자 정리
- 3단계: 재귀 이해
- 부록 C 문제 출처