├── .gitignore ├── LICENSE.txt ├── PEP8_short.pdf ├── README.md ├── discrete_optimization.pdf └── theory ├── complexity.pdf ├── dp.ipynb ├── euclidean_algorithm.pdf ├── graph_shortest_ru.pdf ├── graph_storage_ru.pdf ├── graph_traverse_ru.pdf ├── hashing_en.pdf ├── hashing_ru.pdf ├── heap_ru.pdf ├── ll_en.pdf ├── ll_ru.pdf ├── mst_ru.pdf ├── quadratic_sortings.pdf ├── quasilinear_sortings.pdf ├── searches.pdf ├── sieve_of_eratosthenes.pdf └── spec_case_sortings.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | .idea 3 | test/* 4 | .vscode -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Maxim Abramov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PEP8_short.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/PEP8_short.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MIPT algo course 2 | Добро пожаловать в репозиторий, посвященый курсу по алгоритмам и структурам данных. 3 | Здесь будут выкладываться ссылки на всякий полезный для понимания курса материал.
4 | К тому же напомню, что основное в нашем курсе - это изучение алгоритмов и структур данных. 5 | В перспективе вы можете перейти на другой язык программирования, который будет для Вас более удобным. 6 | Или это будут требования на работе. 7 | Сами алгоритмы от этого не изменятся, поэтому стоит не просто заучивать их код наизусть, а так же понять принцип их 8 | работы. Однако, это не означает, что на изучение языка стоит забить. 9 | Он является частью нашего курса, и Вы его будете использовать на протяжении как минимум года. 10 | 11 | ## Подготовка к работе 12 | Для работы вам понадобится установить интерпретатор Python 3 на ваш компьютер. 13 | Для удобства написания кода, дебага и тд вам понадобится удобная среда разработки. 14 | 15 | ### Интерпретатор Python 16 | Чистый интрепретатор (без дополнительный модулей) можно скачать с [оф. сайта](https://www.python.org/). 17 | На UNIX подобных системах чистый интерпретатор устанавливается через пакетный менеджер. Например для Ubuntu и его 18 | производных: `sudo apt install python3`
19 | [Anaconda](https://www.anaconda.com/distribution/) - интерпретатор с предустановленным набором библиотек. 20 | 21 | ### IDE (среда разработки) 22 | [Visual Studio Code](https://code.visualstudio.com/#alt-downloads)
23 | [PyCharm](https://www.jetbrains.com/pycharm/). Есть как платная (Professional), так и бесплатная (Community) версии. 24 | Можно получить [студенческую лицензию](https://jetbrains.ru/students/classroom-licenses/free-classroom-licenses/) от 25 | JetBrains.
26 | [Spyder](https://www.spyder-ide.org/)
27 | [Visual Studio](https://visualstudio.microsoft.com/vs/). 28 | В личном кабинете на [mipt.ru](https://mipt.ru) есть инструкция о том, как получить лицензионное ПО от Microsoft. 29 | Обычно VS используется для программирования на C++ и C#, но он поддерживает и Python (возможно потребуется установка 30 | дополнительных модулей). 31 | 32 | ## Полезные ссылки 33 | 1. [E-maxx](http://e-maxx.ru/algo/) - отличный онлайн сборник алгоритмов. 34 | 2. [Онлайн курс по Python](https://ru.coursera.org/learn/diving-in-python). Курс от Mail.ru и МФТИ. Доступ к просмотру 35 | видео, вроде, является бесплатным. В курсе довольно хорошо рассказываются основы языка + примеры. Для тех, кому 36 | интересно, дальше освещаются темы, которые в нашем курсе не затрагиваются. 37 | 3. [Документация по Python3](https://docs.python.org/3/) - тут есть вся информация о встроенных функциях и стандартных 38 | библиотеках. Кроме этого там можно найти хороший туториал. 39 | 4. [PEP8](https://www.python.org/dev/peps/pep-0008/) - общепринятый стандарт по написанию кода на языке Python. 40 | [Короткая версия](PEP8_short.pdf). 41 | 5. [Дискретная оптимизация](discrete_optimization.pdf) - неплохой учебник, в котором часть темы по временной сложности 42 | и около того. Кроме этого, там есть материалы по теории графов и не только. 43 | 6. [Викиконспекты](https://neerc.ifmo.ru/wiki) - материалы программированию и алгоритмам университета ИТМО. 44 | 45 | ## Теория по алгоритмам 46 | Большая часть теории основана на материалах E-maxx, Викиконспектов, которые в свою очередь основываются на материалах 47 | книги авторства Томаса Кормена и др. Алгоритмы: Построение и анализ. 48 | 49 | 0. [Временная сложность](theory/complexity.pdf) (пока только на англ., материал на русском смотрите в учебнике по 50 | дискретной оптимизации) 51 | 1. Теория чисел 52 | 1. [Алгоритм Евклида](theory/euclidean_algorithm.pdf) 53 | 2. [Решето Эратосфена](theory/sieve_of_eratosthenes.pdf) 54 | 3. Расширенный алгоритм Евклида 55 | 2. Сортировки и поиск 56 | 1. [Квадратичные сортировки](theory/quadratic_sortings.pdf) 57 | 2. [Сортировки с квазилинейной сложностью](theory/quasilinear_sortings.pdf) 58 | 3. [Сортировки для особых случаев](theory/spec_case_sortings.pdf) 59 | 4. [Поиск элементов в массиве](theory/searches.pdf) 60 | 3. Алгоритмы на строки 61 | 1. [Префикс-функция](https://e-maxx.ru/algo/prefix_function) 62 | 2. [Z-функция](https://e-maxx.ru/algo/z_function) 63 | 3. Разбор выражений 64 | 4. [Динамическое программирование](theory/dp.ipynb). Так же почитать можно [тут](https://neerc.ifmo.ru/wiki/index.php?title=Динамическое_программирование). 65 | 5. [Хеширование](theory/hashing_ru.pdf) 66 | 6. Графы 67 | 1. [Хранение графов](theory/graph_storage_ru.pdf) 68 | 2. [Обходы](theory/graph_traverse_ru.pdf) 69 | 3. [Пути минимального веса](theory/graph_shortest_ru.pdf) 70 | 4. [Остовные деревья](theory/mst_ru.pdf) 71 | 5. Асимптотически сложные задачи 72 | 7. Теория игр 73 | 8. Структуры данных 74 | 1. [Связные списки](theory/ll_ru.pdf) 75 | 2. [Куча](theory/heap_ru.pdf) 76 | 3. [Система непересекающихся множеств](https://e-maxx.ru/algo/dsu) 77 | 4. Двоичные деревья поиска 78 | 79 | ## Algorithms theory 80 | Theese articles mostly based on E-maxx, neerc.ifmo.ru, which are based on Thomas Korman's book Introduction to 81 | ALgorithms. 82 | 83 | 0. [Time complexity](theory/complexity.pdf) 84 | 1. Number theory 85 | 1. Euclidean algorithm 86 | 2. Sieve of Eratosthenes 87 | 3. Extended Euclidean algorithm 88 | 2. Sortings and searches 89 | 1. Quadratic 90 | 2. Quasilinear 91 | 3. Sortings for special cases 92 | 4. Elements search in array 93 | 3. String algorithms 94 | 1. Prefix function 95 | 2. Z function 96 | 3. Tokenization 97 | 4. Dynamic programming 98 | 5. [Hashing](theory/hashing_en.pdf) 99 | 6. Graphs theory 100 | 1. Storage in memory 101 | 2. Traverse 102 | 3. Shortest paths 103 | 4. Minimum spanning trees 104 | 5. Асимптотически сложные задачи 105 | 7. Game theory 106 | 8. Data structures 107 | 1. [Linked lists](theory/ll_en.pdf) 108 | 2. Heap 109 | 3. Disjoint set union 110 | 4. Binary search trees 111 | 112 | ## Контакты со мной 113 | Абрамов Максим Петрович
114 | +7(929)574-91-51
115 | Telegram: @stiimo
116 | maksim.abramov@phystech.edu
117 | https://vk.com/stiimo
118 | -------------------------------------------------------------------------------- /discrete_optimization.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/discrete_optimization.pdf -------------------------------------------------------------------------------- /theory/complexity.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/complexity.pdf -------------------------------------------------------------------------------- /theory/dp.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Динамическое программирование" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Это способ решения задач путем разбиения их на меньшие подзадачи. ДП применимо к задачам с *оптимальной подструктурой*, т.е. оптимальное решение задачи может быть построено из оптимальных решений подзадач. Как видно из определения, обычно задачи ДП заключаются в поиске максимального/минимального решения задачи. Но есть ряд других задач, для которых применим этот способ. Например, посчитать кол-во решений задачи, некоторые задачи теории игр и т.д..
\n", 15 | "Метод ДП имеет два варианта решения задач: с начала и с конца. В первом случае мы просто в цикле(кол-во воженных циклов зависит от размерности задачи) пробегаем от \"самых маленьких\" задач, для которых решение уже известно или ищется очень просто, к \"большим\" задачам. Во втором случае решение сводится к следующим шагам:\n", 16 | "1. Разбиваем задачу на меньшие подзадачи\n", 17 | "2. Для них рекурсивно применяем этот алгоритм\n", 18 | "3. Используем посчитанные ответы подзадач для решения задачи.\n", 19 | "\n", 20 | "Отсюда становится понятно, что решение с конца обязательно использует рекурсию. Условием выхода из рекурсии будет подзадача для которой ответ уже известен или считается легко.
\n", 21 | "Каким бы способом не решалась задача, всегда необходимо знать рекуррентное соотношение, по которому будут определяться переходы из одной задачи к другой." 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Пример на поиск количества решений\n", 29 | "Типичным примером задачи на ДП является вычисление n-ого числа Фибоначчи. Как мы знаем, рекуррентное соотношение тут следующее:\n", 30 | "Fn=Fn-1+Fn-2, будем считать, что 1 и 2 числа Фибоначчи равны 1. Состояниями в такой задаче является номер числа Фибоначчи, а переходами - изменение номера на -1 и -2. Теперь переформулируем задачу: имеем лестницу c n ступеньками (нумерация с 1). Начинаем с 1. Мы можем подняться на 1 или 2 ступеньки за шаг. Сколькими способами мы можем добраться до последней ступеньки. Очевидно, что мы имеем рекуррентное соотношение из задачи с числами Фибоначчи. Кол-во способов добраться до 1 ступеньки равна 1 (мы с нее и начинаем). Для 2 ступеньки так же ответ 1, т.к. мы просто одим единственным шагом поднимаемся на нее с 1. В итоге подсчет кол-ва способов сводится к вычислению n-ого числа Фибоначчи." 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "## Пример на поиск оптимального решения\n", 38 | "Переформулируем нашу задачу со ступеньками следующим образом: теперь шагая по ступенькам, мы теряем или зарабатываем баллы. За каждой ступенькой закреплено целое число - кол-во баллов, на которое изменяется на счетчик. Если оно отрицательное, мы теряем баллы, иначе зарабатываем. Наша цель, набрать максимальное кол-во баллов, дойдя до последней ступеньки. Шаги мы можем совершать те же, что и в предыдущей задачи, спускаться вниз нельзя. Для конкретности считаем, что за нулевой ступенькой закреплено 0 баллов, изначально мы начинаем с 0 баллами. Ответом для n = 0 будет 0, для n = 1 - кол-во баллов, закрепеленное за 1 ступенькой. Для всех последующих n справедлива следующая рекуррентная формула: f(n)=max(f(n-1), f(n-2)) + cn, где cn - кол-во баллов на n ступеньке. " 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": { 44 | "collapsed": true 45 | }, 46 | "source": [ 47 | "## Мемоизация\n", 48 | "**Мемоизация** (англ. memoization) — сохранение результатов выполнения функций для предотвращения повторных вычислений.
\n", 49 | "Как можно было заметить, при рекурсивном вычислении ответа мы можем не один раз приходить к одной и той же подзадаче. И при каждом таком вызове мы будем решать ее заного, причем ответ на нее меняться не будет. Для того, чтобы избежать ненужных вычислений, можно воспользоваться идеей запоминания вычиленных ранее значений с целью последующего их использования. Для этого нам просто нужен будет массив, в котором будут храниться ответы для разных состояний. Так на очередном вызове функции в рекурсии мы сначала проверяем массив на наличие ответа для текущего состояния. Если он посчитан, мы просто возвращаем этот ответ. Иначе мы решаем подзадачу, запоминаем в массив ответ и возвращаем этот ответ. Размер массива должен совпадать с кол-вом состоянии для данной задачи. Рассматривая рекурсивное решение задачи с числами Фибоначчи, нам нужен массив длины n+1, где 0 и 1 ячейка проинициализированы ответами, а остальные значения неопределены. После того, как мы рекурсивно посчитаем числа Фибоначчи, используя созданный нами массив, мы сможем уже без лишних вычислений вывести любое число Фибоначчи, номер которого не превышает n (т.к. мы запускали функцию поиска для этого числа)." 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "## Восстановление ответа\n", 57 | "Нередко в задачах ДП требуется вывести не просто ответ, а последовательность действий, которая приводит к нему. Для этого, как в случае мемоизации, понадобится массив размером, чтобы вмещать все состояния. Только в каждой ячейке мы будем хранить сделанный нами переход, чтобы попасть в данное состояние, либо хранить само состояние, из которого мы пришли. Рассмотрим задачу со ступеньками и баллами. Для восстановления ответа будем хранить номер ступеньки, с которой мы пришли на данную ступеньку. Для 0 ступеньки предыдущей будет -1 или какое-нибудь другое значение, чтобы обозначить начало маршрута. Восстановление ответа делаетсяю, начиная с конца. Мы просто будем записывать в массив для ответа номера ступенек начиная с n. Мы будем \"шагать обратно\" номерам ступенек, используя массив и не забывая записывать в массив ступеньки, по которым мы возвращаемся. Как только мы упремся в начало, т.е. в 0 ступеньку, у которой нет предыдущей ступеньки, мы заканчиваем восстановление ответа. Далее нам просто надо будет распечатать наш массив с маршрутом в обратном порядке. " 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "## Многомерная динамика\n", 65 | "Задачи на ДП не ограничиваются одним измерением. Вам придется сталкиваться с задачами, где состояния задачи опеределяются несколькими параметрами (мне приходилось решать задачу от 6 параметров). Но по факту они не сильно отличаются в сложности и принципы их решения не меняются. Создается массив для записи ответов. Кол-во измерений массива равняется кол-ву параметров. Есть состояния, для которых решение известно или ищется легко. После решения задачи, ответ будет лежать в последней ячейке массива. Примером такой задачи может быть двумерное поле `N*M`, где надо найти кол-во способов добраться из верхней левой клетки в нижнюю правую. Допустимые ходы - шаг на одну клетку вниз или вправо. " 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "## ДП: более сложные виды задач\n", 73 | "Выше мы рассмотрели довольно тривиальные задачи ДП. Но этим не ограничивается класс задач, решаемых таким способом. На деле есть более сложные задачи, решаемые с помощью ДП, но имеющие более хитрый подход. В таких случаях состояния и переходы выделить уже сложнее, но все же сделать реально, т.к. на этом основывается решение всех задач ДП. Другие виды ДП:\n", 74 | "1. Динамика на подотрезках\n", 75 | "2. Динамика на подмножествах\n", 76 | "3. Динамика на поддеревьях\n", 77 | "4. Динамика по профилю\n", 78 | "5. Динамика по изломанному профилю\n", 79 | "\n", 80 | "Подробно расписывать тут я их не буду. Если интересно, теоретический материал можно найти в интернете." 81 | ] 82 | } 83 | ], 84 | "metadata": { 85 | "kernelspec": { 86 | "display_name": "Python 3", 87 | "language": "python", 88 | "name": "python3" 89 | }, 90 | "language_info": { 91 | "codemirror_mode": { 92 | "name": "ipython", 93 | "version": 3 94 | }, 95 | "file_extension": ".py", 96 | "mimetype": "text/x-python", 97 | "name": "python", 98 | "nbconvert_exporter": "python", 99 | "pygments_lexer": "ipython3", 100 | "version": "3.5.2" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 2 105 | } -------------------------------------------------------------------------------- /theory/euclidean_algorithm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/euclidean_algorithm.pdf -------------------------------------------------------------------------------- /theory/graph_shortest_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/graph_shortest_ru.pdf -------------------------------------------------------------------------------- /theory/graph_storage_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/graph_storage_ru.pdf -------------------------------------------------------------------------------- /theory/graph_traverse_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/graph_traverse_ru.pdf -------------------------------------------------------------------------------- /theory/hashing_en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/hashing_en.pdf -------------------------------------------------------------------------------- /theory/hashing_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/hashing_ru.pdf -------------------------------------------------------------------------------- /theory/heap_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/heap_ru.pdf -------------------------------------------------------------------------------- /theory/ll_en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/ll_en.pdf -------------------------------------------------------------------------------- /theory/ll_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/ll_ru.pdf -------------------------------------------------------------------------------- /theory/mst_ru.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/mst_ru.pdf -------------------------------------------------------------------------------- /theory/quadratic_sortings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/quadratic_sortings.pdf -------------------------------------------------------------------------------- /theory/quasilinear_sortings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/quasilinear_sortings.pdf -------------------------------------------------------------------------------- /theory/searches.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/searches.pdf -------------------------------------------------------------------------------- /theory/sieve_of_eratosthenes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/sieve_of_eratosthenes.pdf -------------------------------------------------------------------------------- /theory/spec_case_sortings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stiimo/mipt_algo_course/cbede7106320fa006b2b15d5fba7aef9bfd93d3a/theory/spec_case_sortings.pdf --------------------------------------------------------------------------------