├── .ipynb_checkpoints ├── 01. 深度遍历二叉树-checkpoint.ipynb ├── 02. 层次遍历二叉树-checkpoint.ipynb ├── 03. 括号匹配-checkpoint.ipynb ├── 04. 哈希表的使用-checkpoint.ipynb ├── 05. 多指针操作-checkpoint.ipynb ├── 06. 链表反转-checkpoint.ipynb ├── 07. 基础排序算法的对比-checkpoint.ipynb ├── 08. 递归-checkpoint.ipynb ├── 09. LRU-checkpoint.ipynb └── 10. 二分查找-checkpoint.ipynb ├── 01. 深度遍历二叉树.ipynb ├── 02. 层次遍历二叉树.ipynb ├── 03. 括号匹配.ipynb ├── 04. 哈希表的使用.ipynb ├── 05. 多指针操作.ipynb ├── 06. 链表反转.ipynb ├── 07. 基础排序算法的对比.ipynb ├── 08. 递归.ipynb ├── 09. LRU.ipynb ├── 10. 二分查找.ipynb ├── README.md ├── backet-match-stack.png ├── base_sort_algorithms.jpg ├── base_sort_algorithms.png ├── binary_search.png ├── binary_tree.png ├── bread_visit_tree.png ├── bubble-sort.jpg ├── deep_visit_tree.png ├── fibonacci-spiral.gif ├── hashmap-two-number-sum.png ├── heap-sort.png ├── linked-list-circle.png ├── linked-list-reverse.png ├── lru.jpg ├── quick-sort.png ├── weixin_gzh_erweima.jpg └── 互联网公司十大算法面试题.pptx /.ipynb_checkpoints/01. 深度遍历二叉树-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 深度优先遍历二叉树\n", 8 | "\n", 9 | "深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。\n", 10 | "\n", 11 | "沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。\n", 12 | "\n", 13 | "这一过程一直进行到已发现从源节点可达的所有节点为止。\n", 14 | "\n", 15 | "如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。\n", 16 | "\n", 17 | "\n", 18 | "" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "class Node(object):\n", 28 | " def __init__(self, data, left=None, right=None):\n", 29 | " self.data = data\n", 30 | " self.left = left\n", 31 | " self.right = right" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "tree = Node(\n", 41 | " 1, \n", 42 | " Node(\n", 43 | " 2, \n", 44 | " Node(4),\n", 45 | " Node(5,Node(7), Node(8))),\n", 46 | " Node(3, \n", 47 | " Node(6))\n", 48 | ")" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "## 1、使用栈stack实现" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "def deep_visit(root):\n", 65 | " \"\"\"深度遍历二叉树\"\"\"\n", 66 | " if not root: \n", 67 | " return\n", 68 | " stack = [root]\n", 69 | " while stack:\n", 70 | " # list.pop默认移除最后一个元素\n", 71 | " current = stack.pop()\n", 72 | " print(current.data, end=',')\n", 73 | " \n", 74 | " if current.right:\n", 75 | " stack.append(current.right)\n", 76 | " \n", 77 | " if current.left:\n", 78 | " stack.append(current.left)" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [ 87 | "deep_visit(tree)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "## 2、使用递归实现" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "def deep_visit(root):\n", 104 | " \"\"\"深度遍历二叉树\"\"\"\n", 105 | " if not root: return\n", 106 | " print(root.data, end=\",\")\n", 107 | " deep_visit(root.left)\n", 108 | " deep_visit(root.right)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "metadata": {}, 115 | "outputs": [], 116 | "source": [ 117 | "deep_visit(tree)" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": null, 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [] 126 | } 127 | ], 128 | "metadata": { 129 | "kernelspec": { 130 | "display_name": "Python 3", 131 | "language": "python", 132 | "name": "python3" 133 | }, 134 | "language_info": { 135 | "codemirror_mode": { 136 | "name": "ipython", 137 | "version": 3 138 | }, 139 | "file_extension": ".py", 140 | "mimetype": "text/x-python", 141 | "name": "python", 142 | "nbconvert_exporter": "python", 143 | "pygments_lexer": "ipython3", 144 | "version": "3.7.3" 145 | } 146 | }, 147 | "nbformat": 4, 148 | "nbformat_minor": 2 149 | } 150 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/02. 层次遍历二叉树-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 层次遍历二叉树\n", 8 | "\n", 9 | "广度优先搜索算法(英语:Breadth-First-Search,缩写为BFS),又译作宽度优先搜索,或横向优先搜索,是一种图形搜索算法。\n", 10 | "\n", 11 | "简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点。\n", 12 | "\n", 13 | "如果所有节点均被访问,则算法中止。\n", 14 | "\n", 15 | "\n", 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "class Node(object):\n", 26 | " def __init__(self, data, left=None, right=None):\n", 27 | " self.data = data\n", 28 | " self.left = left\n", 29 | " self.right = right" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 2, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "tree = Node(\n", 39 | " 1, \n", 40 | " Node(\n", 41 | " 2, \n", 42 | " Node(4),\n", 43 | " Node(5,Node(7), Node(8))),\n", 44 | " Node(3, \n", 45 | " Node(6))\n", 46 | ")" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 3, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "def level_visit(root):\n", 56 | " # 使用列表模拟queue\n", 57 | " queue = [root]\n", 58 | " while queue:\n", 59 | " # 删除list的最开始的元素\n", 60 | " current = queue.pop(0)\n", 61 | " print(current.data, end=\",\")\n", 62 | " if current.left:\n", 63 | " queue.append(current.left)\n", 64 | " if current.right:\n", 65 | " queue.append(current.right)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 4, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "1,2,3,4,5,6,7,8," 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "level_visit(tree)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [] 91 | } 92 | ], 93 | "metadata": { 94 | "kernelspec": { 95 | "display_name": "Python 3", 96 | "language": "python", 97 | "name": "python3" 98 | }, 99 | "language_info": { 100 | "codemirror_mode": { 101 | "name": "ipython", 102 | "version": 3 103 | }, 104 | "file_extension": ".py", 105 | "mimetype": "text/x-python", 106 | "name": "python", 107 | "nbconvert_exporter": "python", 108 | "pygments_lexer": "ipython3", 109 | "version": "3.7.3" 110 | } 111 | }, 112 | "nbformat": 4, 113 | "nbformat_minor": 2 114 | } 115 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/03. 括号匹配-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 括号匹配算法\n", 8 | "\n", 9 | "判断括号是否正确关闭了\n", 10 | "\n", 11 | "sentence=\"0{abc}{de}(f)[(g)]9\" \n", 12 | "sentence=\"0{abc}{de}(f)[(g)9\"\n", 13 | "\n", 14 | "\n", 15 | "\n", 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "def bracket_match(sentence):\n", 26 | " # 括号的反向匹配,用于遇到了右括号,获取对应的最括号\n", 27 | " brackets_map = {\n", 28 | " ')': '(' , \n", 29 | " ']': '[' , \n", 30 | " '}': '{' ,\n", 31 | " '>': '<' \n", 32 | " }\n", 33 | "\n", 34 | " # 使用栈存储左括号列表,每次遇到右括号就匹配栈顶\n", 35 | " stack = [] \n", 36 | " label = True\n", 37 | " for iter_char in sentence:\n", 38 | " # 遇到了左括号,则入stack\n", 39 | " if iter_char in brackets_map.values():\n", 40 | " stack.append(iter_char)\n", 41 | " \n", 42 | " # 遇到了右括号,则进行判断\n", 43 | " if iter_char in brackets_map:\n", 44 | " # 如果栈已经空了,则返回匹配失败\n", 45 | " if len(stack) < 1:\n", 46 | " return False\n", 47 | " \n", 48 | " if brackets_map[iter_char] == stack[-1]:\n", 49 | " stack.pop() # 如果该括号匹配成功,则弹出栈顶\n", 50 | " else:\n", 51 | " return False # 否则,直接失败\n", 52 | " \n", 53 | " # 如果栈不为空,返回失败\n", 54 | " if stack != []:\n", 55 | " return False\n", 56 | " return True\n" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 2, 62 | "metadata": {}, 63 | "outputs": [ 64 | { 65 | "data": { 66 | "text/plain": [ 67 | "True" 68 | ] 69 | }, 70 | "execution_count": 2, 71 | "metadata": {}, 72 | "output_type": "execute_result" 73 | } 74 | ], 75 | "source": [ 76 | "sentence=\"0{abc}{de}(f)[(g)]9\"\n", 77 | "bracket_match(sentence)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 3, 83 | "metadata": {}, 84 | "outputs": [ 85 | { 86 | "data": { 87 | "text/plain": [ 88 | "False" 89 | ] 90 | }, 91 | "execution_count": 3, 92 | "metadata": {}, 93 | "output_type": "execute_result" 94 | } 95 | ], 96 | "source": [ 97 | "sentence=\"0{abc}{de}(f)[(g)9\"\n", 98 | "bracket_match(sentence)" 99 | ] 100 | } 101 | ], 102 | "metadata": { 103 | "kernelspec": { 104 | "display_name": "Python 3", 105 | "language": "python", 106 | "name": "python3" 107 | }, 108 | "language_info": { 109 | "codemirror_mode": { 110 | "name": "ipython", 111 | "version": 3 112 | }, 113 | "file_extension": ".py", 114 | "mimetype": "text/x-python", 115 | "name": "python", 116 | "nbconvert_exporter": "python", 117 | "pygments_lexer": "ipython3", 118 | "version": "3.7.3" 119 | } 120 | }, 121 | "nbformat": 4, 122 | "nbformat_minor": 2 123 | } 124 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/04. 哈希表的使用-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 哈希表\n", 8 | "\n", 9 | "特点:查找速度是O(1) \n", 10 | "用于:空间换时间\n", 11 | "\n", 12 | "常常用于缓存,然后快速查找,提升性能\n", 13 | "\n", 14 | "" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "问题描述:无序数组中找出和为N的两个数 \n", 22 | "\n", 23 | "例如,nums = [1, 4, 3, 2, 6, 5]中找出和为target = 6的序列 \n", 24 | "\n", 25 | "答案:[(1, 5), (4, 2)]。" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "def find(num_list, sum_value):\n", 35 | " \"\"\"\n", 36 | " @param num_list:数字列表\n", 37 | " @param sum_value:数字之和\n", 38 | " \"\"\"\n", 39 | " # 第一遍历,O(N),建立哈希表\n", 40 | " hash_dict = {}\n", 41 | " for val in num_list:\n", 42 | " if val not in hash_dict:\n", 43 | " hash_dict[val] = 0\n", 44 | " # value是这个值的出现次数\n", 45 | " hash_dict[val] += 1\n", 46 | " print(hash_dict)\n", 47 | " \n", 48 | " # 第二次遍历,O(N)\n", 49 | " # 遇到每个元素val,判断sum_value-val在不在哈希表中\n", 50 | " for val in num_list:\n", 51 | " if hash_dict[val] == 0:\n", 52 | " continue\n", 53 | " # 使用次数减一\n", 54 | " hash_dict[val] -= 1\n", 55 | " # 如果减去的数字也在表中,则说明匹配成功\n", 56 | " if hash_dict.get(sum_value-val, 0) > 0:\n", 57 | " print(val, sum_value-val) \n", 58 | " hash_dict[sum_value-val] -= 1" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 2, 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "{1: 1, 4: 2, 3: 2, 2: 1, 6: 1, 5: 1}\n", 71 | "1 5\n", 72 | "4 2\n", 73 | "3 3\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "num_list = [1, 4, 3, 2, 3, 4, 6, 5]\n", 79 | "find(num_list, 6)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": {}, 86 | "outputs": [], 87 | "source": [] 88 | } 89 | ], 90 | "metadata": { 91 | "kernelspec": { 92 | "display_name": "Python 3", 93 | "language": "python", 94 | "name": "python3" 95 | }, 96 | "language_info": { 97 | "codemirror_mode": { 98 | "name": "ipython", 99 | "version": 3 100 | }, 101 | "file_extension": ".py", 102 | "mimetype": "text/x-python", 103 | "name": "python", 104 | "nbconvert_exporter": "python", 105 | "pygments_lexer": "ipython3", 106 | "version": "3.7.3" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 2 111 | } 112 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/05. 多指针操作-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 多指针操作\n", 8 | "\n", 9 | "\n", 10 | "用于链表反转、链表有环、最大回文数等问题\n", 11 | "\n", 12 | "\n", 13 | "问题:判断链表是否有环\n", 14 | "方法:快指针和慢指针\n", 15 | "\n", 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "class Node:\n", 26 | " def __init__(self, data):\n", 27 | " self.data = data\n", 28 | " self.next = None" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "def list_have_loop(link_list):\n", 38 | " \"\"\" 默认返回没有环路 \"\"\"\n", 39 | " plow = pfast = link_list\n", 40 | " # pfast走的快,判断它是否结束\n", 41 | " while pfast and pfast.next:\n", 42 | " plow = plow.next\n", 43 | " pfast = pfast.next.next\n", 44 | " if plow == pfast:\n", 45 | " return True\n", 46 | " return False" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 3, 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "data": { 56 | "text/plain": [ 57 | "True" 58 | ] 59 | }, 60 | "execution_count": 3, 61 | "metadata": {}, 62 | "output_type": "execute_result" 63 | } 64 | ], 65 | "source": [ 66 | "root, p1, p2, p3, p4, p5 = (\n", 67 | " Node(0), Node(1), Node(2), Node(3), Node(4), Node(5))\n", 68 | "\n", 69 | "# p5的next是p2,构成环路\n", 70 | "root.next, p1.next, p2.next, p3.next, p4.next, p5.next = (\n", 71 | " p1, p2, p3, p4, p5, p2)\n", 72 | "\n", 73 | "list_have_loop(root)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [] 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.7.3" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 2 105 | } 106 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/06. 链表反转-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": { 5 | "image.png": { 6 | "image/png": "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OussO/bYY9ucE/hD50nJKSoq8jZXV1fbP//5T9tiiy1sjz32CDzU3nvvPe/3zjvv3GZ7pB8vvPBCRCWqrq7OO/3ll1+2kpKSsEntu+++lpaWFnY/OyAQSwJq15dffrldc801bRQtDVg8//zzHc6KBkAiKVo9fX9+//339uWXX4bNr6zpEj1XpESGk4022sjGjh0bbjfbIQABCEAgCQigaCVBJZHF7hPYdtttTUpVsLz00ku26aabttksJexvf/ubzZs3zzIzM00j5LvsskvrX3p6eI9buQB+9dVXlpWVZTvttJOXbnl5ud1www1eWp9++qndfffd9sgjj3jHfP311972Qw891FMEpQxKSdPnOeecY0cffXSbvOnHkUceGbIswQcef/zxwZva/K6qqvLy0GYjPyCQoAQuvvhiGzZsWNjcTZ8+3bMkhz3AzHPR7en788knn7Tzzz8/Uja8fVIeIymQF1xwgf3pT39qNx0OgAAEIACBxCWAopW4dUPOokhg//33t9ra2ta5VdnZ2W1Sl9JRUFDgbZNboJMffvjBSktL3c92P9944w3vGClKsmA5keImxUcdMFmZZsyY4XZZY2Ojffjhh62/3ZeVK1e6r20+f/Ob31hDQ0ObbYE/brzxRquoqPAsb65Mgfvd94yMDPeVTwgkPIEDDzzQJk6cGDafUnDkshtJYnF/Tpo0yS666KKw2dC9/9xzz3lWt7333jvscTvuuGPYfeyAAAQgAIHkIICilRz1RC67SeCee+6xV1991Y477jg77LDD7Prrr29NUa4+UorOOOMMu/LKK1u360skRaXNgT/+eO2117xvOk8KlBMpenJn0pwsdbTUETvzzDNNE+MfffRRC+U6mJeX505v86mR/Uii4BpStH73u99Zv379Ih3KPgikFIFY3J/bb7+96S+caG6oFC1Z2S+77LJwh7EdAhCAAAR8QABFyweVSBE6RmDrrbf23PIU1EKBJ1xnSCPhmkdVXFzcsYTCHCWF7aGHHvJcAWfOnGmDBg1qc6QUq9NPP90LqKHReY2uFxYW2lZbbeW5Fm644YbtBs9wCcrl8X//+5/72eZTk+0lUuZCKWsq989+9rM25/ADAn4nEMv7UyzPPffcNoMtjq9cFyVvv/22/frXv3ab23xqrlqk+ZVtDuYHBCAAAQgkLAEUrYStGjIWbQLquFx66aV2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dJHA008/ba+99loXz+Y0CEAAAl0jgKLVNW6cBQEIQAACEIAABCAAAQhAICwBFK2waNiRKgTkcvHll1/asmXLOlzktWvX2meffWaVlZUdPifeBzY0NNg333xjLS0tYbMiBjNmzOhUuerq6jx+33//fcS0w16UHQlBQO6c3333ndXX1/dYfjrSBhcuXGg9NY9p9erVNmvWLFM+OiJdadvNzc02f/58++KLL6yzboI6V3Wguoh0n3Yk74lwTGd5K8/J+GwNZN3ZMse6jSU730DWfIdAMhBA0UqGWiKPUSPw+OOP24ABA+zss882vRCPOOIIGzx4sG2zzTa24YYb2kYbbWQPPvhg2OtpjpEmteuc7bff3gYOHOjNOXrqqafanPP6669711GajY2Nbfbpx09/+lNv/7777rvePnW2dA3lU53CrsrDDz/spXHeeeeZ8jd8+HDbcsstbcyYMW3KWFtba1dddZUNGzbMY7DDDjt45dpss83skUceCXv56dOn21577WX9+vXz+G266abeeccee+x6wS4uvfRSLy9OMT3ggAO837fffnvY9NnR8wSkVP/yl7+00aNHm+p74sSJXn2eccYZtnTp0jYZ0H61yVdffbXNdvdD7Uz7f/e737lN1pE2uNVWW3nnSVE/8MADbezYsTZy5Ej7yU9+YjU1Na1pdfbLdttt56Urxe2BBx7wyqY2vu2221r//v3t8MMPNwUQCCWdaduB5z/00EOm+2D8+PE2adIk7zlx6qmnmu6xSCLF7OCDD/byqzoQaz1bTjjhhB5TOiPlpyv7usNb1+vos1WKqJ5lamvnn3/+elldtWqVbbLJJt7+c8891yoqKrzvl112mXfsW2+95f3Wc7C70p0yx7qNdZRvd5lwPgQg0JYAilZbHvzyOQGNMKuzrxHj3Xff3V544QVP8dhll12soKDAlixZYieeeKL30g9EoRFwdYT04lbHbaeddrLjjjvO67TNnTvXjjzySPvtb3/beoqUMIksRNOmTWvdri8awVRnVfl4991317MeffTRR96k+d69e3sdhjYnd+KH8qxrfPvtt3bSSSe1zo1avHix19FQUuoAqix/+tOfvA6JlCyVRR09MVJHT3/BImVU573zzjs2aNAgO+yww2yfffaxzMxMkzK79dZb2wcffNB62pAhQzyFNCMjw9s2atQo77eUNCQ+BNRhlcIr5UD1IsVjxx139Kww//73v02DABr9dqK2pL9QAwc6Rm1J+wOVio60werqau+8Sy65xF555RXvcrqG0snLy3OX7/SnS/eGG25obf977LGHp1TKavfcc8/ZlClT2uRXF+ls23YZe/HFF73rSGmaMGGCdx+pM3/ffffZoYce6g5b7/Oll17ylDJ99unTxxv80bNGzyMNdGgQqDsDLutdsIc2dJV3Z5+tGhSQUq+2dtNNN9l7773XpkSnnXaaKfCFnkt6rqWnp3vPGg2OSQoLC73fUoi7K10tcyzbWGf5dpcJ50MAAm0JZPrBPaFtpqf5rAAAIABJREFUkfgFgfAEXHvXpGiNmkvRcS9cjZ5rFP3DDz+0G2+80es0paWleYndcsstpo6QFAON0mtU3MnLL7/sKV06RsrG1KlTLTs72/vUBGx1Hp3ipXPUMXAj9epQKg977rmnS86ef/5577vy4vLburMTX9y5ur5Gx++9915PcdOI7s477+ylreAU6sQNHTrUG/WXxcvJY489Zuq0qLO322672VFHHeXt+uGHH+ycc84xWd60/89//rNlZWV5+zSafPzxx5ssehrJl5IpFqeccor3p1Hoqqoqu+6662zy5MneOS6f7rp89jwBhdc/6KCDTPUlRfqaa66xnJwc78LqpKq9ys30yiuv9KydgTlSfbVXZ26/+4zUBl3aTz75pDfIcdZZZ3nWNHWQ3fnumM58unNvvvlm+81vfmNS5Fw71X159NFHe4MmaufdadvKkwYl1O51T/z1r3+1M888szWr6lSffvrprb+VL5c33Qu6h2R1+cUvfmFXX3215ebmesdqnwZIlNdf//rXrUpoa0IJ9sWVqTO8VYTOPlt1jiyuUmz1nBE/DeqI25133mnPPvus15Y1WCBlVaJj//GPf9hFF13kWfWfeeYZb7vLs/ejC//c+Z0pc1een8paV9tYV/h2AQWnQAACYQhg0QoDhs3+J6BOjVOyVFqNnqtjKZEbk6xbEs0X+ctf/uJ9l4IQqGRpo0bJL774Ym//BRdc4H3q33777ed9D3a1cr/lWiR54403vE/3zylaCkUcLbn22ms9Nz8pVLJYqRMri4Y6CJK///3vXgck8HqyUv3qV7/yNqmTKkuc5A9/+IPXMdxiiy28jqHrvGpfaWmp3XPPPVZUVOSlj2ughyzh/kl5lkKlwQa1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zjv25ptvejwKCwvbPb4jBzz55JN21FFHWVlZmU2ZMqUjp8T9mLPOOsuuu+4622STTWzQoEExy88999xjCxYssA022MAyMjK6fN2HH37YTj/9dCsqKrLx48d3OZ14nuindjtr1ix78MEHbaONNrL8/Pz1sL733nt2wgknePfIpEmT1tvf3oampiY77rjjbO7cubb99tuHPfyFF16wW265xYYNG2b9+vULe1yi7Vi1apVdfPHF3n3Rt2/fqGTv+eeft7PPPtu7zzbddNM2aX700Ud28sknm67blfpok9iPP9544w3venrfbL755qEOSfhtzz33nH3wwQcxy/9LL71kv/71ry0tLc0mTJhgr7/+uvee1/MxKyurw7y++OILu+KKK2zp0qW2xRZbdPg8vQ9vvfVW23HHHcM+j3lOdRin8ZzqOCt3JM8pRyIxPjMTIxs9mwtZ7f785z/bZpttZvvvv3/rxa688kr7+OOPW3935supp55qEydOXO+UO++8s8tpBid27rnn2pgxY4I32+233245OTleJ8ntXLFihf33v/91P9v9VIf8l7/8ZdjjbrvtNrvrrrvsn//8px155JFhj9OORx55xNTZ/9e//mWHHnpoxGM7unPt2rWml9Hy5cs7ekpcj5s/f77df//93otVHdJoydtvv+11gsMpUFJE1fHLzc21hQsXduuyYv3ZZ5+1YV5bW9up9jx27NiQnXENaOhPHfrADqo68VISOyrbbrttyPvOne+ndqsOqjp6dXV19rvf/c4VsfXzlVdeMXXupdh3RZ5++mnTn+o4ktx4442mzqM6+smkgP/xj3/0nkt6lujZFA1Rp1ssdtlll/WSW716tbdv1KhR6+3r6oYlS5Z4ikKyKlmNjY127bXXeu1Uz/PLLrvMU4C6yqMj50nRVR1tt9123ufhhx9uDQ0NVlBQYEcffbSXh1ADF8Fp67mk95qesRrQiCQrV660//3vf967WQMkkuzsbO9aoc7jORWKSuhtPKdCc4m0ledUJDqx35cSitaMGTM8S4M6q0899ZRNnjzZI33SSSe1Ubw6gz/cCNe7775rTzzxRGeSCnusXgqhFK3zzjvPszRpNNrJDz/8YNreUZGiFknReuutt7yRJGehknVLo3R64U+dOrXNZTRaKdEIXkdl3rx59tVXX4U9XKOJEr3sNDoTTtSpCcUo3PE9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" 7 | } 8 | }, 9 | "cell_type": "markdown", 10 | "metadata": {}, 11 | "source": [ 12 | "# 链表反转\n", 13 | "\n", 14 | "三个指针的应用:原列表的头指针、新列表的头指针、原列表的头指针的第二个指针(第二指针)\n", 15 | "\n", 16 | "linked-list-reverse.png![image.png](attachment:image.png)" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "class Node:\n", 26 | " def __init__(self, data):\n", 27 | " self.data = data\n", 28 | " self.next = None\n", 29 | "\n", 30 | "root, p1, p2, p3, p4, p5 = (\n", 31 | " Node(0), Node(1), Node(2), Node(3), Node(4), Node(5))\n", 32 | "\n", 33 | "root.next, p1.next, p2.next, p3.next, p4.next = (\n", 34 | " p1, p2, p3, p4, p5 )" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 2, 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "0,1,2,3,4,5," 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "def print_list(root):\n", 52 | " iter_node = root\n", 53 | " while iter_node:\n", 54 | " print(iter_node.data, end=\",\")\n", 55 | " iter_node = iter_node.next\n", 56 | "print_list(root)" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 3, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "def reverse_list(root):\n", 66 | " \"\"\" 链表反转 \"\"\"\n", 67 | " if not root or not root.next:\n", 68 | " return root\n", 69 | " \n", 70 | " # 指向新的首节点\n", 71 | " new_root = None\n", 72 | " curr_node = root\n", 73 | " while curr_node:\n", 74 | " # 保存当前节点的下一个节点\n", 75 | " next_node = curr_node.next \n", 76 | " # 让当前节点的下一个节点变成新列表的root\n", 77 | " curr_node.next = new_root\n", 78 | " new_root = curr_node\n", 79 | " # 当前节点往下遍历\n", 80 | " curr_node = next_node\n", 81 | " return new_root" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 4, 87 | "metadata": {}, 88 | "outputs": [ 89 | { 90 | "name": "stdout", 91 | "output_type": "stream", 92 | "text": [ 93 | "5,4,3,2,1,0," 94 | ] 95 | } 96 | ], 97 | "source": [ 98 | "print_list(reverse_list(root))" 99 | ] 100 | } 101 | ], 102 | "metadata": { 103 | "kernelspec": { 104 | "display_name": "Python 3", 105 | "language": "python", 106 | "name": "python3" 107 | }, 108 | "language_info": { 109 | "codemirror_mode": { 110 | "name": "ipython", 111 | "version": 3 112 | }, 113 | "file_extension": ".py", 114 | "mimetype": "text/x-python", 115 | "name": "python", 116 | "nbconvert_exporter": "python", 117 | "pygments_lexer": "ipython3", 118 | "version": "3.7.3" 119 | } 120 | }, 121 | "nbformat": 4, 122 | "nbformat_minor": 2 123 | } 124 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/07. 基础排序算法的对比-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 基础排序算法\n", 8 | "\n", 9 | "不一定要实现代码,但是要知道思路,以及时间复杂度" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "### 1.直接插入排序\n", 24 | "原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。\n", 25 | "要点:设立哨兵,作为临时存储和判断数组边界之用。" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "### 2.希尔排序\n", 33 | "原理:又称增量缩小排序。先将序列按增量划分为元素个数相同的若干组,使用直接插入排序法进行排序,然后不断缩小增量直至为1,最后使用直接插入排序完成排序。\n", 34 | "要点:增量的选择以及排序最终以1为增量进行排序结束。" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "### 3.冒泡排序 *\n", 42 | "重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。\n", 43 | "\n", 44 | "越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。\n", 45 | "\n", 46 | "\n" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### 4.快速排序 *\n", 54 | "通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。\n", 55 | "\n", 56 | "" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "### 5.直接选择排序\n", 64 | "原理:将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序。 " 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "### 6.堆排序 *\n", 72 | "原理:利用大根堆或小根堆思想,首先建立堆,然后将堆首与堆尾交换,堆尾之后为有序区。\n", 73 | "要点:建堆、交换、调整堆\n", 74 | "\n", 75 | "" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "### 7.归并排序\n", 83 | "原理:将原序列划分为有序的两个序列,然后利用归并算法进行合并,合并之后即为有序序列。\n", 84 | "要点:归并、分治" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "### 8.基数排序\n", 92 | "原理:将数字按位数划分出n个关键字,每次针对一个关键字进行排序,然后针对排序后序列进行下一个关键字的排序,循环至所有关键字都使用过则排序完成。\n", 93 | "要点:对关键字的选取,元素分配收集。" 94 | ] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Python 3", 100 | "language": "python", 101 | "name": "python3" 102 | }, 103 | "language_info": { 104 | "codemirror_mode": { 105 | "name": "ipython", 106 | "version": 3 107 | }, 108 | "file_extension": ".py", 109 | "mimetype": "text/x-python", 110 | "name": "python", 111 | "nbconvert_exporter": "python", 112 | "pygments_lexer": "ipython3", 113 | "version": "3.7.3" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 2 118 | } 119 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/08. 递归-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 递归\n", 8 | "看到代码好简单,让你自己写就一头蒙逼" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "### 1. 计算斐波那契数列\n", 16 | "\n", 17 | "" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 1, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "def recur_fibo(n):\n", 27 | " \"\"\"递归函数\n", 28 | " 输出斐波那契数列,n=0则是0,n=1则是1,否则是前面两个数字的和\n", 29 | " \"\"\"\n", 30 | " if n <= 1:\n", 31 | " return n\n", 32 | " else:\n", 33 | " return(recur_fibo(n-1) + recur_fibo(n-2))" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "data": { 43 | "text/plain": [ 44 | "55" 45 | ] 46 | }, 47 | "execution_count": 2, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "recur_fibo(10)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "### 2. 使用递归-深度遍历二叉树\n", 61 | "\n", 62 | "" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "class Node(object):\n", 72 | " def __init__(self, data, left=None, right=None):\n", 73 | " self.data = data\n", 74 | " self.left = left\n", 75 | " self.right = right\n", 76 | "\n", 77 | "tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node( 2, Node(5), Node(4) ))" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "def deep_visit(root):\n", 87 | " \"\"\"深度遍历二叉树\"\"\"\n", 88 | " if not root: return\n", 89 | " print(root.data, end=\",\")\n", 90 | " deep_visit(root.left)\n", 91 | " deep_visit(root.right)" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 5, 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "1,3,7,0,6,2,5,4," 104 | ] 105 | } 106 | ], 107 | "source": [ 108 | "deep_visit(tree)" 109 | ] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3", 115 | "language": "python", 116 | "name": "python3" 117 | }, 118 | "language_info": { 119 | "codemirror_mode": { 120 | "name": "ipython", 121 | "version": 3 122 | }, 123 | "file_extension": ".py", 124 | "mimetype": "text/x-python", 125 | "name": "python", 126 | "nbconvert_exporter": "python", 127 | "pygments_lexer": "ipython3", 128 | "version": "3.7.3" 129 | } 130 | }, 131 | "nbformat": 4, 132 | "nbformat_minor": 2 133 | } 134 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/09. LRU-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## LRU Least Recently Used" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。\n", 15 | "该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。在有限的空间中存储对象时,当空间满时,会按一定的原则删除原有的对象,常用的原则(算法)有LRU,FIFO等\n", 16 | "\n", 17 | "" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 1, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "class LRUCache(object):\n", 27 | " def __init__(self, capacity):\n", 28 | " self.capacity = capacity\n", 29 | " # 存储数据\n", 30 | " self.values = {}\n", 31 | " # 存储使用的顺序\n", 32 | " self.access = []\n", 33 | "\n", 34 | " def get(self, key):\n", 35 | " \"\"\"查询的时候,会影响元素的位置,把这个元素放到最后\"\"\"\n", 36 | " if key in self.values:\n", 37 | " self.access.remove(key)\n", 38 | " self.access.append(key)\n", 39 | " return self.values[key]\n", 40 | " else:\n", 41 | " return -1\n", 42 | "\n", 43 | " def set(self, key, value):\n", 44 | " if key in self.values:\n", 45 | " self.access.remove(key)\n", 46 | " elif len(self.values) >= self.capacity:\n", 47 | " # 清理最不常用的元素\n", 48 | " del self.values[self.access.pop(0)]\n", 49 | " self.access.append(key)\n", 50 | " self.values[key] = value\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 2, 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "name": "stdout", 60 | "output_type": "stream", 61 | "text": [ 62 | "{5: 50, 6: 60, 7: 70, 8: 80, 9: 90} [5, 6, 7, 8, 9]\n" 63 | ] 64 | } 65 | ], 66 | "source": [ 67 | "lru = LRUCache(5)\n", 68 | "for i in range(5,10):\n", 69 | " lru.set(i, 10*i)\n", 70 | "print(lru.values, lru.access)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 3, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "{5: 50, 6: 60, 7: 70, 8: 80, 9: 90} [6, 7, 8, 9, 5]\n", 83 | "{5: 50, 7: 70, 8: 80, 9: 90, 10: 100} [7, 8, 9, 5, 10]\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "lru.get(5)\n", 89 | "print(lru.values, lru.access)\n", 90 | "lru.set(10,100)\n", 91 | "print(lru.values, lru.access)" 92 | ] 93 | } 94 | ], 95 | "metadata": { 96 | "kernelspec": { 97 | "display_name": "Python 3", 98 | "language": "python", 99 | "name": "python3" 100 | }, 101 | "language_info": { 102 | "codemirror_mode": { 103 | "name": "ipython", 104 | "version": 3 105 | }, 106 | "file_extension": ".py", 107 | "mimetype": "text/x-python", 108 | "name": "python", 109 | "nbconvert_exporter": "python", 110 | "pygments_lexer": "ipython3", 111 | "version": "3.7.3" 112 | } 113 | }, 114 | "nbformat": 4, 115 | "nbformat_minor": 2 116 | } 117 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/10. 二分查找-checkpoint.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 | "否则利用中间位置记录将表分成前、后两个子表\n", 17 | "如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。\n", 18 | "重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。\n", 19 | "\n", 20 | "\n", 21 | "\n", 22 | "\n", 23 | "伪装:找出有问题的git版本号 \n", 24 | "伪装:最近120天的数据中,有一天的格式有问题,找出这一天" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "def binary_search(alist, item):\n", 34 | " \"\"\"二分查找 非递归方式,返回结果索引\"\"\"\n", 35 | " n = len(alist)\n", 36 | " start = 0\n", 37 | " end = n - 1\n", 38 | " # 通过循环,不断变更start和end,来缩小搜索范围,每次缩小一半\n", 39 | " while start <= end:\n", 40 | " mid = (start + end) // 2\n", 41 | " if alist[mid] == item:\n", 42 | " return mid\n", 43 | " elif item < alist[mid]:\n", 44 | " end = mid - 1\n", 45 | " else:\n", 46 | " start = mid + 1\n", 47 | " return -1" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 2, 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "data": { 57 | "text/plain": [ 58 | "2" 59 | ] 60 | }, 61 | "execution_count": 2, 62 | "metadata": {}, 63 | "output_type": "execute_result" 64 | } 65 | ], 66 | "source": [ 67 | "binary_search([1,2,3,4,5,6], 3)" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 3, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "text/plain": [ 78 | "-1" 79 | ] 80 | }, 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "binary_search([1,2,3,4,5,6], 3.5)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [] 96 | } 97 | ], 98 | "metadata": { 99 | "kernelspec": { 100 | "display_name": "Python 3", 101 | "language": "python", 102 | "name": "python3" 103 | }, 104 | "language_info": { 105 | "codemirror_mode": { 106 | "name": "ipython", 107 | "version": 3 108 | }, 109 | "file_extension": ".py", 110 | "mimetype": "text/x-python", 111 | "name": "python", 112 | "nbconvert_exporter": "python", 113 | "pygments_lexer": "ipython3", 114 | "version": "3.7.3" 115 | } 116 | }, 117 | "nbformat": 4, 118 | "nbformat_minor": 2 119 | } 120 | -------------------------------------------------------------------------------- /01. 深度遍历二叉树.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 深度优先遍历二叉树\n", 8 | "\n", 9 | "深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。\n", 10 | "\n", 11 | "沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。\n", 12 | "\n", 13 | "这一过程一直进行到已发现从源节点可达的所有节点为止。\n", 14 | "\n", 15 | "如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。\n", 16 | "\n", 17 | "\n", 18 | "" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 3, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "class Node(object):\n", 28 | " def __init__(self, data, left=None, right=None):\n", 29 | " self.data = data\n", 30 | " self.left = left\n", 31 | " self.right = right" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 4, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "tree = Node(\n", 41 | " 1, \n", 42 | " Node(\n", 43 | " 2, \n", 44 | " Node(4),\n", 45 | " Node(5,Node(7), Node(8))),\n", 46 | " Node(3, \n", 47 | " Node(6))\n", 48 | ")" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "## 1、使用栈stack实现" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 5, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "def deep_visit(root):\n", 65 | " \"\"\"深度遍历二叉树\"\"\"\n", 66 | " if not root: \n", 67 | " return\n", 68 | " stack = [root]\n", 69 | " while stack:\n", 70 | " # list.pop默认移除最后一个元素\n", 71 | " current = stack.pop()\n", 72 | " print(current.data, end=',')\n", 73 | " \n", 74 | " if current.right:\n", 75 | " stack.append(current.right)\n", 76 | " \n", 77 | " if current.left:\n", 78 | " stack.append(current.left)" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 6, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "1,2,4,5,7,8,3,6," 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "deep_visit(tree)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "## 2、使用递归实现" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "def deep_visit(root):\n", 112 | " \"\"\"深度遍历二叉树\"\"\"\n", 113 | " if not root: return\n", 114 | " print(root.data, end=\",\")\n", 115 | " deep_visit(root.left)\n", 116 | " deep_visit(root.right)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "deep_visit(tree)" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [] 134 | } 135 | ], 136 | "metadata": { 137 | "kernelspec": { 138 | "display_name": "Python 3", 139 | "language": "python", 140 | "name": "python3" 141 | }, 142 | "language_info": { 143 | "codemirror_mode": { 144 | "name": "ipython", 145 | "version": 3 146 | }, 147 | "file_extension": ".py", 148 | "mimetype": "text/x-python", 149 | "name": "python", 150 | "nbconvert_exporter": "python", 151 | "pygments_lexer": "ipython3", 152 | "version": "3.7.3" 153 | } 154 | }, 155 | "nbformat": 4, 156 | "nbformat_minor": 2 157 | } 158 | -------------------------------------------------------------------------------- /02. 层次遍历二叉树.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 层次遍历二叉树\n", 8 | "\n", 9 | "广度优先搜索算法(英语:Breadth-First-Search,缩写为BFS),又译作宽度优先搜索,或横向优先搜索,是一种图形搜索算法。\n", 10 | "\n", 11 | "简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点。\n", 12 | "\n", 13 | "如果所有节点均被访问,则算法中止。\n", 14 | "\n", 15 | "\n", 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "class Node(object):\n", 26 | " def __init__(self, data, left=None, right=None):\n", 27 | " self.data = data\n", 28 | " self.left = left\n", 29 | " self.right = right" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 2, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "tree = Node(\n", 39 | " 1, \n", 40 | " Node(\n", 41 | " 2, \n", 42 | " Node(4),\n", 43 | " Node(5,Node(7), Node(8))),\n", 44 | " Node(3, \n", 45 | " Node(6))\n", 46 | ")" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 3, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "def level_visit(root):\n", 56 | " # 使用列表模拟queue\n", 57 | " queue = [root]\n", 58 | " while queue:\n", 59 | " # 删除list的最开始的元素\n", 60 | " current = queue.pop(0)\n", 61 | " print(current.data, end=\",\")\n", 62 | " if current.left:\n", 63 | " queue.append(current.left)\n", 64 | " if current.right:\n", 65 | " queue.append(current.right)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 4, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "1,2,3,4,5,6,7,8," 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "level_visit(tree)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [] 91 | } 92 | ], 93 | "metadata": { 94 | "kernelspec": { 95 | "display_name": "Python 3", 96 | "language": "python", 97 | "name": "python3" 98 | }, 99 | "language_info": { 100 | "codemirror_mode": { 101 | "name": "ipython", 102 | "version": 3 103 | }, 104 | "file_extension": ".py", 105 | "mimetype": "text/x-python", 106 | "name": "python", 107 | "nbconvert_exporter": "python", 108 | "pygments_lexer": "ipython3", 109 | "version": "3.7.3" 110 | } 111 | }, 112 | "nbformat": 4, 113 | "nbformat_minor": 2 114 | } 115 | -------------------------------------------------------------------------------- /03. 括号匹配.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 括号匹配算法\n", 8 | "\n", 9 | "判断括号是否正确关闭了\n", 10 | "\n", 11 | "sentence=\"0{abc}{de}(f)[(g)]9\" \n", 12 | "sentence=\"0{abc}{de}(f)[(g)9\"\n", 13 | "\n", 14 | "\n", 15 | "\n", 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "def bracket_match(sentence):\n", 26 | " # 括号的反向匹配,用于遇到了右括号,获取对应的最括号\n", 27 | " brackets_map = {\n", 28 | " ')': '(' , \n", 29 | " ']': '[' , \n", 30 | " '}': '{' ,\n", 31 | " '>': '<' \n", 32 | " }\n", 33 | "\n", 34 | " # 使用栈存储左括号列表,每次遇到右括号就匹配栈顶\n", 35 | " stack = [] \n", 36 | " label = True\n", 37 | " for iter_char in sentence:\n", 38 | " # 遇到了左括号,则入stack\n", 39 | " if iter_char in brackets_map.values():\n", 40 | " stack.append(iter_char)\n", 41 | " \n", 42 | " # 遇到了右括号,则进行判断\n", 43 | " if iter_char in brackets_map:\n", 44 | " # 如果栈已经空了,则返回匹配失败\n", 45 | " if len(stack) < 1:\n", 46 | " return False\n", 47 | " \n", 48 | " if brackets_map[iter_char] == stack[-1]:\n", 49 | " stack.pop() # 如果该括号匹配成功,则弹出栈顶\n", 50 | " else:\n", 51 | " return False # 否则,直接失败\n", 52 | " \n", 53 | " # 如果栈不为空,返回失败\n", 54 | " if stack != []:\n", 55 | " return False\n", 56 | " return True\n" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 2, 62 | "metadata": {}, 63 | "outputs": [ 64 | { 65 | "data": { 66 | "text/plain": [ 67 | "True" 68 | ] 69 | }, 70 | "execution_count": 2, 71 | "metadata": {}, 72 | "output_type": "execute_result" 73 | } 74 | ], 75 | "source": [ 76 | "sentence=\"0{abc}{de}(f)[(g)]9\"\n", 77 | "bracket_match(sentence)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 3, 83 | "metadata": {}, 84 | "outputs": [ 85 | { 86 | "data": { 87 | "text/plain": [ 88 | "False" 89 | ] 90 | }, 91 | "execution_count": 3, 92 | "metadata": {}, 93 | "output_type": "execute_result" 94 | } 95 | ], 96 | "source": [ 97 | "sentence=\"0{abc}{de}(f)[(g)9\"\n", 98 | "bracket_match(sentence)" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "Python 3", 112 | "language": "python", 113 | "name": "python3" 114 | }, 115 | "language_info": { 116 | "codemirror_mode": { 117 | "name": "ipython", 118 | "version": 3 119 | }, 120 | "file_extension": ".py", 121 | "mimetype": "text/x-python", 122 | "name": "python", 123 | "nbconvert_exporter": "python", 124 | "pygments_lexer": "ipython3", 125 | "version": "3.7.3" 126 | } 127 | }, 128 | "nbformat": 4, 129 | "nbformat_minor": 2 130 | } 131 | -------------------------------------------------------------------------------- /04. 哈希表的使用.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 哈希表\n", 8 | "\n", 9 | "特点:查找速度是O(1) \n", 10 | "用于:空间换时间\n", 11 | "\n", 12 | "常常用于缓存,然后快速查找,提升性能\n", 13 | "\n", 14 | "" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "问题描述:无序数组中找出和为N的两个数 \n", 22 | "\n", 23 | "例如,nums = [1, 4, 3, 2, 6, 5]中找出和为target = 6的序列 \n", 24 | "\n", 25 | "答案:[(1, 5), (4, 2)]。" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "def find(num_list, sum_value):\n", 35 | " \"\"\"\n", 36 | " @param num_list:数字列表\n", 37 | " @param sum_value:数字之和\n", 38 | " \"\"\"\n", 39 | " # 第一遍历,O(N),建立哈希表\n", 40 | " hash_dict = {}\n", 41 | " for val in num_list:\n", 42 | " if val not in hash_dict:\n", 43 | " hash_dict[val] = 0\n", 44 | " # value是这个值的出现次数\n", 45 | " hash_dict[val] += 1\n", 46 | " print(hash_dict)\n", 47 | " \n", 48 | " # 第二次遍历,O(N)\n", 49 | " # 遇到每个元素val,判断sum_value-val在不在哈希表中\n", 50 | " for val in num_list:\n", 51 | " if hash_dict[val] == 0:\n", 52 | " continue\n", 53 | " # 使用次数减一\n", 54 | " hash_dict[val] -= 1\n", 55 | " # 如果减去的数字也在表中,则说明匹配成功\n", 56 | " if hash_dict.get(sum_value-val, 0) > 0:\n", 57 | " print(val, sum_value-val) \n", 58 | " hash_dict[sum_value-val] -= 1" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 2, 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "{1: 1, 4: 2, 3: 2, 2: 1, 6: 1, 5: 1}\n", 71 | "1 5\n", 72 | "4 2\n", 73 | "3 3\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "num_list = [1, 4, 3, 2, 3, 4, 6, 5]\n", 79 | "find(num_list, 6)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": {}, 86 | "outputs": [], 87 | "source": [] 88 | } 89 | ], 90 | "metadata": { 91 | "kernelspec": { 92 | "display_name": "Python 3", 93 | "language": "python", 94 | "name": "python3" 95 | }, 96 | "language_info": { 97 | "codemirror_mode": { 98 | "name": "ipython", 99 | "version": 3 100 | }, 101 | "file_extension": ".py", 102 | "mimetype": "text/x-python", 103 | "name": "python", 104 | "nbconvert_exporter": "python", 105 | "pygments_lexer": "ipython3", 106 | "version": "3.7.3" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 2 111 | } 112 | -------------------------------------------------------------------------------- /05. 多指针操作.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 多指针操作\n", 8 | "\n", 9 | "\n", 10 | "用于链表反转、链表有环、最大回文数等问题\n", 11 | "\n", 12 | "\n", 13 | "问题:判断链表是否有环\n", 14 | "方法:快指针和慢指针\n", 15 | "\n", 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "class Node:\n", 26 | " def __init__(self, data):\n", 27 | " self.data = data\n", 28 | " self.next = None" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "def list_have_loop(link_list):\n", 38 | " \"\"\" 默认返回没有环路 \"\"\"\n", 39 | " plow = pfast = link_list\n", 40 | " # pfast走的快,判断它是否结束\n", 41 | " while pfast and pfast.next:\n", 42 | " plow = plow.next\n", 43 | " pfast = pfast.next.next\n", 44 | " if plow == pfast:\n", 45 | " return True\n", 46 | " return False" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 3, 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "data": { 56 | "text/plain": [ 57 | "True" 58 | ] 59 | }, 60 | "execution_count": 3, 61 | "metadata": {}, 62 | "output_type": "execute_result" 63 | } 64 | ], 65 | "source": [ 66 | "root, p1, p2, p3, p4, p5 = (\n", 67 | " Node(0), Node(1), Node(2), Node(3), Node(4), Node(5))\n", 68 | "\n", 69 | "# p5的next是p2,构成环路\n", 70 | "root.next, p1.next, p2.next, p3.next, p4.next, p5.next = (\n", 71 | " p1, p2, p3, p4, p5, p2)\n", 72 | "\n", 73 | "list_have_loop(root)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [] 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.7.3" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 2 105 | } 106 | -------------------------------------------------------------------------------- /06. 链表反转.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": { 5 | "image.png": { 6 | "image/png": "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OussO/bYY9ucE/hD50nJKSoq8jZXV1fbP//5T9tiiy1sjz32CDzU3nvvPe/3zjvv3GZ7pB8vvPBCRCWqrq7OO/3ll1+2kpKSsEntu+++lpaWFnY/OyAQSwJq15dffrldc801bRQtDVg8//zzHc6KBkAiKVo9fX9+//339uWXX4bNr6zpEj1XpESGk4022sjGjh0bbjfbIQABCEAgCQigaCVBJZHF7hPYdtttTUpVsLz00ku26aabttksJexvf/ubzZs3zzIzM00j5LvsskvrX3p6eI9buQB+9dVXlpWVZTvttJOXbnl5ud1www1eWp9++qndfffd9sgjj3jHfP311972Qw891FMEpQxKSdPnOeecY0cffXSbvOnHkUceGbIswQcef/zxwZva/K6qqvLy0GYjPyCQoAQuvvhiGzZsWNjcTZ8+3bMkhz3AzHPR7en788knn7Tzzz8/Uja8fVIeIymQF1xwgf3pT39qNx0OgAAEIACBxCWAopW4dUPOokhg//33t9ra2ta5VdnZ2W1Sl9JRUFDgbZNboJMffvjBSktL3c92P9944w3vGClKsmA5keImxUcdMFmZZsyY4XZZY2Ojffjhh62/3ZeVK1e6r20+f/Ob31hDQ0ObbYE/brzxRquoqPAsb65Mgfvd94yMDPeVTwgkPIEDDzzQJk6cGDafUnDkshtJYnF/Tpo0yS666KKw2dC9/9xzz3lWt7333jvscTvuuGPYfeyAAAQgAIHkIICilRz1RC67SeCee+6xV1991Y477jg77LDD7Prrr29NUa4+UorOOOMMu/LKK1u360skRaXNgT/+eO2117xvOk8KlBMpenJn0pwsdbTUETvzzDNNE+MfffRRC+U6mJeX505v86mR/Uii4BpStH73u99Zv379Ih3KPgikFIFY3J/bb7+96S+caG6oFC1Z2S+77LJwh7EdAhCAAAR8QABFyweVSBE6RmDrrbf23PIU1EKBJ1xnSCPhmkdVXFzcsYTCHCWF7aGHHvJcAWfOnGmDBg1qc6QUq9NPP90LqKHReY2uFxYW2lZbbeW5Fm644YbtBs9wCcrl8X//+5/72eZTk+0lUuZCKWsq989+9rM25/ADAn4nEMv7UyzPPffcNoMtjq9cFyVvv/22/frXv3ab23xqrlqk+ZVtDuYHBCAAAQgkLAEUrYStGjIWbQLquFx66aV2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dJHA008/ba+99loXz+Y0CEAAAl0jgKLVNW6cBQEIQAACEIAABCAAAQhAICwBFK2waNiRKgTkcvHll1/asmXLOlzktWvX2meffWaVlZUdPifeBzY0NNg333xjLS0tYbMiBjNmzOhUuerq6jx+33//fcS0w16UHQlBQO6c3333ndXX1/dYfjrSBhcuXGg9NY9p9erVNmvWLFM+OiJdadvNzc02f/58++KLL6yzboI6V3Wguoh0n3Yk74lwTGd5K8/J+GwNZN3ZMse6jSU730DWfIdAMhBA0UqGWiKPUSPw+OOP24ABA+zss882vRCPOOIIGzx4sG2zzTa24YYb2kYbbWQPPvhg2OtpjpEmteuc7bff3gYOHOjNOXrqqafanPP6669711GajY2Nbfbpx09/+lNv/7777rvePnW2dA3lU53CrsrDDz/spXHeeeeZ8jd8+HDbcsstbcyYMW3KWFtba1dddZUNGzbMY7DDDjt45dpss83skUceCXv56dOn21577WX9+vXz+G266abeeccee+x6wS4uvfRSLy9OMT3ggAO837fffnvY9NnR8wSkVP/yl7+00aNHm+p74sSJXn2eccYZtnTp0jYZ0H61yVdffbXNdvdD7Uz7f/e737lN1pE2uNVWW3nnSVE/8MADbezYsTZy5Ej7yU9+YjU1Na1pdfbLdttt56Urxe2BBx7wyqY2vu2221r//v3t8MMPNwUQCCWdaduB5z/00EOm+2D8+PE2adIk7zlx6qmnmu6xSCLF7OCDD/byqzoQaz1bTjjhhB5TOiPlpyv7usNb1+vos1WKqJ5lamvnn3/+elldtWqVbbLJJt7+c8891yoqKrzvl112mXfsW2+95f3Wc7C70p0yx7qNdZRvd5lwPgQg0JYAilZbHvzyOQGNMKuzrxHj3Xff3V544QVP8dhll12soKDAlixZYieeeKL30g9EoRFwdYT04lbHbaeddrLjjjvO67TNnTvXjjzySPvtb3/beoqUMIksRNOmTWvdri8awVRnVfl4991317MeffTRR96k+d69e3sdhjYnd+KH8qxrfPvtt3bSSSe1zo1avHix19FQUuoAqix/+tOfvA6JlCyVRR09MVJHT3/BImVU573zzjs2aNAgO+yww2yfffaxzMxMkzK79dZb2wcffNB62pAhQzyFNCMjw9s2atQo77eUNCQ+BNRhlcIr5UD1IsVjxx139Kww//73v02DABr9dqK2pL9QAwc6Rm1J+wOVio60werqau+8Sy65xF555RXvcrqG0snLy3OX7/SnS/eGG25obf977LGHp1TKavfcc8/ZlClT2uRXF+ls23YZe/HFF73rSGmaMGGCdx+pM3/ffffZoYce6g5b7/Oll17ylDJ99unTxxv80bNGzyMNdGgQqDsDLutdsIc2dJV3Z5+tGhSQUq+2dtNNN9l7773XpkSnnXaaKfCFnkt6rqWnp3vPGg2OSQoLC73fUoi7K10tcyzbWGf5dpcJ50MAAm0JZPrBPaFtpqf5rAAAIABJREFUkfgFgfAEXHvXpGiNmkvRcS9cjZ5rFP3DDz+0G2+80es0paWleYndcsstpo6QFAON0mtU3MnLL7/sKV06RsrG1KlTLTs72/vUBGx1Hp3ipXPUMXAj9epQKg977rmnS86ef/5577vy4vLburMTX9y5ur5Gx++9915PcdOI7s477+ylreAU6sQNHTrUG/WXxcvJY489Zuq0qLO322672VFHHeXt+uGHH+ycc84xWd60/89//rNlZWV5+zSafPzxx5ssehrJl5IpFqeccor3p1Hoqqoqu+6662zy5MneOS6f7rp89jwBhdc/6KCDTPUlRfqaa66xnJwc78LqpKq9ys30yiuv9KydgTlSfbVXZ26/+4zUBl3aTz75pDfIcdZZZ3nWNHWQ3fnumM58unNvvvlm+81vfmNS5Fw71X159NFHe4MmaufdadvKkwYl1O51T/z1r3+1M888szWr6lSffvrprb+VL5c33Qu6h2R1+cUvfmFXX3215ebmesdqnwZIlNdf//rXrUpoa0IJ9sWVqTO8VYTOPlt1jiyuUmz1nBE/DeqI25133mnPPvus15Y1WCBlVaJj//GPf9hFF13kWfWfeeYZb7vLs/ejC//c+Z0pc1een8paV9tYV/h2AQWnQAACYQhg0QoDhs3+J6BOjVOyVFqNnqtjKZEbk6xbEs0X+ctf/uJ9l4IQqGRpo0bJL774Ym//BRdc4H3q33777ed9D3a1cr/lWiR54403vE/3zylaCkUcLbn22ms9Nz8pVLJYqRMri4Y6CJK///3vXgck8HqyUv3qV7/yNqmTKkuc5A9/+IPXMdxiiy28jqHrvGpfaWmp3XPPPVZUVOSlj2ughyzh/kl5lkKlwQa1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zjv25ptvejwKCwvbPb4jBzz55JN21FFHWVlZmU2ZMqUjp8T9mLPOOsuuu+4622STTWzQoEExy88999xjCxYssA022MAyMjK6fN2HH37YTj/9dCsqKrLx48d3OZ14nuindjtr1ix78MEHbaONNrL8/Pz1sL733nt2wgknePfIpEmT1tvf3oampiY77rjjbO7cubb99tuHPfyFF16wW265xYYNG2b9+vULe1yi7Vi1apVdfPHF3n3Rt2/fqGTv+eeft7PPPtu7zzbddNM2aX700Ud28sknm67blfpok9iPP9544w3venrfbL755qEOSfhtzz33nH3wwQcxy/9LL71kv/71ry0tLc0mTJhgr7/+uvee1/MxKyurw7y++OILu+KKK2zp0qW2xRZbdPg8vQ9vvfVW23HHHcM+j3lOdRin8ZzqOCt3JM8pRyIxPjMTIxs9mwtZ7f785z/bZpttZvvvv3/rxa688kr7+OOPW3935supp55qEydOXO+UO++8s8tpBid27rnn2pgxY4I32+233245OTleJ8ntXLFihf33v/91P9v9VIf8l7/8ZdjjbrvtNrvrrrvsn//8px155JFhj9OORx55xNTZ/9e//mWHHnpoxGM7unPt2rWml9Hy5cs7ekpcj5s/f77df//93otVHdJoydtvv+11gsMpUFJE1fHLzc21hQsXduuyYv3ZZ5+1YV5bW9up9jx27NiQnXENaOhPHfrADqo68VISOyrbbrttyPvOne+ndqsOqjp6dXV19rvf/c4VsfXzlVdeMXXupdh3RZ5++mnTn+o4ktx4442mzqM6+smkgP/xj3/0nkt6lujZFA1Rp1ssdtlll/WSW716tbdv1KhR6+3r6oYlS5Z4ikKyKlmNjY127bXXeu1Uz/PLLrvMU4C6yqMj50nRVR1tt9123ufhhx9uDQ0NVlBQYEcffbSXh1ADF8Fp67mk95qesRrQiCQrV660//3vf967WQMkkuzsbO9aoc7jORWKSuhtPKdCc4m0ledUJDqx35cSitaMGTM8S4M6q0899ZRNnjzZI33SSSe1Ubw6gz/cCNe7775rTzzxRGeSCnusXgqhFK3zzjvPszRpNNrJDz/8YNreUZGiFknReuutt7yRJGehknVLo3R64U+dOrXNZTRaKdEIXkdl3rx59tVXX4U9XKOJEr3sNDoTTtSpCcUo3PE9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" 7 | } 8 | }, 9 | "cell_type": "markdown", 10 | "metadata": {}, 11 | "source": [ 12 | "# 链表反转\n", 13 | "\n", 14 | "三个指针的应用:原列表的头指针、新列表的头指针、原列表的头指针的第二个指针(第二指针)\n", 15 | "\n", 16 | "linked-list-reverse.png![image.png](attachment:image.png)" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "class Node:\n", 26 | " def __init__(self, data):\n", 27 | " self.data = data\n", 28 | " self.next = None\n", 29 | "\n", 30 | "root, p1, p2, p3, p4, p5 = (\n", 31 | " Node(0), Node(1), Node(2), Node(3), Node(4), Node(5))\n", 32 | "\n", 33 | "root.next, p1.next, p2.next, p3.next, p4.next = (\n", 34 | " p1, p2, p3, p4, p5 )" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 2, 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "0,1,2,3,4,5," 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "def print_list(root):\n", 52 | " iter_node = root\n", 53 | " while iter_node:\n", 54 | " print(iter_node.data, end=\",\")\n", 55 | " iter_node = iter_node.next\n", 56 | "print_list(root)" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 3, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "def reverse_list(root):\n", 66 | " \"\"\" 链表反转 \"\"\"\n", 67 | " if not root or not root.next:\n", 68 | " return root\n", 69 | " \n", 70 | " # 指向新的首节点\n", 71 | " new_root = None\n", 72 | " curr_node = root\n", 73 | " while curr_node:\n", 74 | " # 保存当前节点的下一个节点\n", 75 | " next_node = curr_node.next \n", 76 | " # 让当前节点的下一个节点变成新列表的root\n", 77 | " curr_node.next = new_root\n", 78 | " new_root = curr_node\n", 79 | " # 当前节点往下遍历\n", 80 | " curr_node = next_node\n", 81 | " return new_root" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 4, 87 | "metadata": {}, 88 | "outputs": [ 89 | { 90 | "name": "stdout", 91 | "output_type": "stream", 92 | "text": [ 93 | "5,4,3,2,1,0," 94 | ] 95 | } 96 | ], 97 | "source": [ 98 | "print_list(reverse_list(root))" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "Python 3", 112 | "language": "python", 113 | "name": "python3" 114 | }, 115 | "language_info": { 116 | "codemirror_mode": { 117 | "name": "ipython", 118 | "version": 3 119 | }, 120 | "file_extension": ".py", 121 | "mimetype": "text/x-python", 122 | "name": "python", 123 | "nbconvert_exporter": "python", 124 | "pygments_lexer": "ipython3", 125 | "version": "3.7.3" 126 | } 127 | }, 128 | "nbformat": 4, 129 | "nbformat_minor": 2 130 | } 131 | -------------------------------------------------------------------------------- /07. 基础排序算法的对比.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 基础排序算法\n", 8 | "\n", 9 | "不一定要实现代码,但是要知道思路,以及时间复杂度" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "### 1.直接插入排序\n", 24 | "原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。\n", 25 | "要点:设立哨兵,作为临时存储和判断数组边界之用。" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "### 2.希尔排序\n", 33 | "原理:又称增量缩小排序。先将序列按增量划分为元素个数相同的若干组,使用直接插入排序法进行排序,然后不断缩小增量直至为1,最后使用直接插入排序完成排序。\n", 34 | "要点:增量的选择以及排序最终以1为增量进行排序结束。" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "### 3.冒泡排序 *\n", 42 | "重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。\n", 43 | "\n", 44 | "越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。\n", 45 | "\n", 46 | "\n" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### 4.快速排序 *\n", 54 | "通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。\n", 55 | "\n", 56 | "" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "### 5.直接选择排序\n", 64 | "原理:将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序。 " 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "### 6.堆排序 *\n", 72 | "原理:利用大根堆或小根堆思想,首先建立堆,然后将堆首与堆尾交换,堆尾之后为有序区。\n", 73 | "要点:建堆、交换、调整堆\n", 74 | "\n", 75 | "" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "### 7.归并排序\n", 83 | "原理:将原序列划分为有序的两个序列,然后利用归并算法进行合并,合并之后即为有序序列。\n", 84 | "要点:归并、分治" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "### 8.基数排序\n", 92 | "原理:将数字按位数划分出n个关键字,每次针对一个关键字进行排序,然后针对排序后序列进行下一个关键字的排序,循环至所有关键字都使用过则排序完成。\n", 93 | "要点:对关键字的选取,元素分配收集。" 94 | ] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Python 3", 100 | "language": "python", 101 | "name": "python3" 102 | }, 103 | "language_info": { 104 | "codemirror_mode": { 105 | "name": "ipython", 106 | "version": 3 107 | }, 108 | "file_extension": ".py", 109 | "mimetype": "text/x-python", 110 | "name": "python", 111 | "nbconvert_exporter": "python", 112 | "pygments_lexer": "ipython3", 113 | "version": "3.7.3" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 2 118 | } 119 | -------------------------------------------------------------------------------- /08. 递归.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 递归\n", 8 | "看到代码好简单,让你自己写就一头蒙逼" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "### 1. 计算斐波那契数列\n", 16 | "\n", 17 | "" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 1, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "def recur_fibo(n):\n", 27 | " \"\"\"递归函数\n", 28 | " 输出斐波那契数列,n=0则是0,n=1则是1,否则是前面两个数字的和\n", 29 | " \"\"\"\n", 30 | " if n <= 1:\n", 31 | " return n\n", 32 | " else:\n", 33 | " return(recur_fibo(n-1) + recur_fibo(n-2))" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "data": { 43 | "text/plain": [ 44 | "55" 45 | ] 46 | }, 47 | "execution_count": 2, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "recur_fibo(10)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "### 2. 使用递归-深度遍历二叉树\n", 61 | "\n", 62 | "" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "class Node(object):\n", 72 | " def __init__(self, data, left=None, right=None):\n", 73 | " self.data = data\n", 74 | " self.left = left\n", 75 | " self.right = right\n", 76 | "\n", 77 | "tree = Node(1, Node(3, Node(7, Node(0)), Node(6)), Node( 2, Node(5), Node(4) ))" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "def deep_visit(root):\n", 87 | " \"\"\"深度遍历二叉树\"\"\"\n", 88 | " if not root: return\n", 89 | " print(root.data, end=\",\")\n", 90 | " deep_visit(root.left)\n", 91 | " deep_visit(root.right)" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 5, 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "1,3,7,0,6,2,5,4," 104 | ] 105 | } 106 | ], 107 | "source": [ 108 | "deep_visit(tree)" 109 | ] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3", 115 | "language": "python", 116 | "name": "python3" 117 | }, 118 | "language_info": { 119 | "codemirror_mode": { 120 | "name": "ipython", 121 | "version": 3 122 | }, 123 | "file_extension": ".py", 124 | "mimetype": "text/x-python", 125 | "name": "python", 126 | "nbconvert_exporter": "python", 127 | "pygments_lexer": "ipython3", 128 | "version": "3.7.3" 129 | } 130 | }, 131 | "nbformat": 4, 132 | "nbformat_minor": 2 133 | } 134 | -------------------------------------------------------------------------------- /09. LRU.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## LRU Least Recently Used" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。\n", 15 | "该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。在有限的空间中存储对象时,当空间满时,会按一定的原则删除原有的对象,常用的原则(算法)有LRU,FIFO等\n", 16 | "\n", 17 | "" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 1, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "class LRUCache(object):\n", 27 | " def __init__(self, capacity):\n", 28 | " self.capacity = capacity\n", 29 | " # 存储数据\n", 30 | " self.values = {}\n", 31 | " # 存储使用的顺序\n", 32 | " self.access = []\n", 33 | "\n", 34 | " def get(self, key):\n", 35 | " \"\"\"查询的时候,会影响元素的位置,把这个元素放到最后\"\"\"\n", 36 | " if key in self.values:\n", 37 | " self.access.remove(key)\n", 38 | " self.access.append(key)\n", 39 | " return self.values[key]\n", 40 | " else:\n", 41 | " return -1\n", 42 | "\n", 43 | " def set(self, key, value):\n", 44 | " if key in self.values:\n", 45 | " self.access.remove(key)\n", 46 | " elif len(self.values) >= self.capacity:\n", 47 | " # 清理最不常用的元素\n", 48 | " del self.values[self.access.pop(0)]\n", 49 | " self.access.append(key)\n", 50 | " self.values[key] = value\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 2, 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "name": "stdout", 60 | "output_type": "stream", 61 | "text": [ 62 | "{5: 50, 6: 60, 7: 70, 8: 80, 9: 90} [5, 6, 7, 8, 9]\n" 63 | ] 64 | } 65 | ], 66 | "source": [ 67 | "lru = LRUCache(5)\n", 68 | "for i in range(5,10):\n", 69 | " lru.set(i, 10*i)\n", 70 | "print(lru.values, lru.access)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 3, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "{5: 50, 6: 60, 7: 70, 8: 80, 9: 90} [6, 7, 8, 9, 5]\n", 83 | "{5: 50, 7: 70, 8: 80, 9: 90, 10: 100} [7, 8, 9, 5, 10]\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "lru.get(5)\n", 89 | "print(lru.values, lru.access)\n", 90 | "lru.set(10,100)\n", 91 | "print(lru.values, lru.access)" 92 | ] 93 | } 94 | ], 95 | "metadata": { 96 | "kernelspec": { 97 | "display_name": "Python 3", 98 | "language": "python", 99 | "name": "python3" 100 | }, 101 | "language_info": { 102 | "codemirror_mode": { 103 | "name": "ipython", 104 | "version": 3 105 | }, 106 | "file_extension": ".py", 107 | "mimetype": "text/x-python", 108 | "name": "python", 109 | "nbconvert_exporter": "python", 110 | "pygments_lexer": "ipython3", 111 | "version": "3.7.3" 112 | } 113 | }, 114 | "nbformat": 4, 115 | "nbformat_minor": 2 116 | } 117 | -------------------------------------------------------------------------------- /10. 二分查找.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 | "否则利用中间位置记录将表分成前、后两个子表\n", 17 | "如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。\n", 18 | "重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。\n", 19 | "\n", 20 | "\n", 21 | "\n", 22 | "\n", 23 | "伪装:找出有问题的git版本号 \n", 24 | "伪装:最近120天的数据中,有一天的格式有问题,找出这一天" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "def binary_search(alist, item):\n", 34 | " \"\"\"二分查找 非递归方式,返回结果索引\"\"\"\n", 35 | " n = len(alist)\n", 36 | " start = 0\n", 37 | " end = n - 1\n", 38 | " # 通过循环,不断变更start和end,来缩小搜索范围,每次缩小一半\n", 39 | " while start <= end:\n", 40 | " mid = (start + end) // 2\n", 41 | " if alist[mid] == item:\n", 42 | " return mid\n", 43 | " elif item < alist[mid]:\n", 44 | " end = mid - 1\n", 45 | " else:\n", 46 | " start = mid + 1\n", 47 | " return -1" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 2, 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "data": { 57 | "text/plain": [ 58 | "2" 59 | ] 60 | }, 61 | "execution_count": 2, 62 | "metadata": {}, 63 | "output_type": "execute_result" 64 | } 65 | ], 66 | "source": [ 67 | "binary_search([1,2,3,4,5,6], 3)" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 3, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "text/plain": [ 78 | "-1" 79 | ] 80 | }, 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "binary_search([1,2,3,4,5,6], 3.5)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [] 96 | } 97 | ], 98 | "metadata": { 99 | "kernelspec": { 100 | "display_name": "Python 3", 101 | "language": "python", 102 | "name": "python3" 103 | }, 104 | "language_info": { 105 | "codemirror_mode": { 106 | "name": "ipython", 107 | "version": 3 108 | }, 109 | "file_extension": ".py", 110 | "mimetype": "text/x-python", 111 | "name": "python", 112 | "nbconvert_exporter": "python", 113 | "pygments_lexer": "ipython3", 114 | "version": "3.7.3" 115 | } 116 | }, 117 | "nbformat": 4, 118 | "nbformat_minor": 2 119 | } 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ant-learn-algorithm 2 | 3 | ## 代码的打开方式 4 | 5 | 不论你是windows、mac、linux,推荐去下载anaconda 6 | 地址为: 7 | https://www.anaconda.com/ 8 | 9 | 下载好之后,进入你电脑的命令行,如果是windows就是cmd命令行,mac/linux就是系统命令行 10 | 11 | 然后使用cd命令切换到这个下载好的代码目录 12 | 13 | 在里面输入:jupyter notebook 14 | 就能打开Python网页版执行器,可以play这个代码了 15 | 16 | ## 欢迎关注我的微信公众号 17 | 18 | 公众号会持续分享Python基础、算法、数据分析、大数据处理、机器学习、推荐系统等领域的干货 19 | 20 | 21 | 22 | ## 送给大家一句话 23 | 学习就像游泳,不要看别人游的多么好,自己得下水才能学会 24 | -------------------------------------------------------------------------------- /backet-match-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/backet-match-stack.png -------------------------------------------------------------------------------- /base_sort_algorithms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/base_sort_algorithms.jpg -------------------------------------------------------------------------------- /base_sort_algorithms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/base_sort_algorithms.png -------------------------------------------------------------------------------- /binary_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/binary_search.png -------------------------------------------------------------------------------- /binary_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/binary_tree.png -------------------------------------------------------------------------------- /bread_visit_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/bread_visit_tree.png -------------------------------------------------------------------------------- /bubble-sort.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/bubble-sort.jpg -------------------------------------------------------------------------------- /deep_visit_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/deep_visit_tree.png -------------------------------------------------------------------------------- /fibonacci-spiral.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/fibonacci-spiral.gif -------------------------------------------------------------------------------- /hashmap-two-number-sum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/hashmap-two-number-sum.png -------------------------------------------------------------------------------- /heap-sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/heap-sort.png -------------------------------------------------------------------------------- /linked-list-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/linked-list-circle.png -------------------------------------------------------------------------------- /linked-list-reverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/linked-list-reverse.png -------------------------------------------------------------------------------- /lru.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/lru.jpg -------------------------------------------------------------------------------- /quick-sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/quick-sort.png -------------------------------------------------------------------------------- /weixin_gzh_erweima.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/weixin_gzh_erweima.jpg -------------------------------------------------------------------------------- /互联网公司十大算法面试题.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peiss/ant-learn-algorithm/9a1d55a5ca783e877374030c70156781040563aa/互联网公司十大算法面试题.pptx --------------------------------------------------------------------------------