├── .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/kl5lkKlwQa1DadkKaPaJouBRIML0ZJQbTAwbVlR1Q432GADk0uWuz8Cj+nKdw0eyG0ssJ3KkieLrOT9999vTbarbVsDM4qmqQGMQCVLCf/85z/37rnWiwR8ERO5aMoCpu9OydIhUhLuuusub5BEikSwe3JAMgn1tTO8u/ps1QCYXOFk9Z89e7an3OpTipTkiiuu8KxWsQLTmTLHso11lW+suHEdCKQCARStVKhlyrgeASkach0MlhEjRrRu0oiy5NNPP/U6Ufn5+a3KU+tBP35Rx02ioBrO3Urzl+SSJV98zQdzImuaru/msrz55ptulzfCrkn06kDIjS9aItfIYFEwD43IqmMr61kocYqW5rKoIyNReSQaVXYWP2/Dj//k/uQsBMFuPYHH8T1+BD7//HPv4ppPF6iAuBypbjWC7urabe/OZ6g2GJie3Bada2ng9u5+10BIqHYqhVIiFzQnrrydbdtuEVxZtULJySefHGpz6yDLIYcc4rndBh+kwR/lX5Is91JneHf12SoecgWUlUoi91AptHLl07NMVq5YSmfKHMs21h2+seTHtSDgZwKZfi4cZYNAOAJypZNLW7D07du3dZObi6IOp0SdNc1jCSXOhUT7dLxGOGXd0ai8OkhycdE8jZUrV5o6uVq0d9dddzUpb+qkaeRRypXmjEn23nvvkB2vUNdub5vyUVxcvN5hcg2TaM5DOFGexET5lgVMx8raJ1HgkHCigAYSnYMkHgEp2RIp2aFE94bcPKMl4dpgYPqat9cTogAYocTd6+4+17ytrrRt3fsaHJEoSEMoCVc2N3jxxBNPhFWk3PPHfYZKP5G2dZS38uzK1Nlnqyuv5rJpUOf++++3r776yjQX9NZbb3W7Y/bZ0TLHuo11l2/MAHIhCPiYAIqWjyuXooUnoAnRHRVNbpfIwqX5WO3JggULWt3wNLoqRUtzVKRoSeFSx0xKljqzslopzbffftsLTNATboOaFB5KXLmkdEYSRWiToqUgGvpzHdNI5+kciY5HEo+AAqRIXD31dA7DtcHA60ZqT4HHdfa73Fg7Il1t2wp446zf4XjqeSNXQHec8qPvmiMn0WCLs4qFy6u7X8PtT5TtHeWt/LoydeXZ6sqruYZStCRSaHv16uV2xeyzo2WOdRuLBt+YQeRCEPApARQtn1YsxYoeARcZT2GoNXG+PQm0HmmeluZvuXlZchuUODcqKVxStDRPS+4nciPUPA0Fn4iWhHKbUtqu86vACJHEhfmWdUtWDqUnZVHnac5XKHHnyI0QSTwCatPq9EmB7qwo4EMocUpDqH3h2mDgsR05JvD4aH/vatvWeepoK6CF7olQVkJFfnMBcFy+pXg55UuRCRUBMZIooqffpDvPVrGQm7YC80jkjq1AP5p3KtfPRJRYt7Hu8k1EhuQJAslGgDlayVZj5DfmBJyLnFzt5G6kl1fwn1yj5Baiz8DAAhphVYhndWrl2iJFSvs12V8iRUsiRUvWLoW0VtRCdcB6Wpw7k3NfCnW9srKy1vllcsvRnBF9SpxbSqjz3D4XUjnUMWyLHwGt7yaR9TWUSDGQS5bWKXJrTblADWrnoUTLHCSzdLVtS0HU2lcS53oYzEFLQoRSUN09qHoIfqa435q3JhdjDXT4TbrzbBULRagUWwUTUah3iYJNaK5sIkqs21h3+SYiQ/IEgWQjgKKVbDVGfmNOQNH1FDBAk+YVqjmUKISu5iVpxFKuRIHiAk0o9LA6VIpaqI6TRFEPpbzJlevuu+/2trlohYFp9MR3rXWlTqIULWdxC76OyiWRlc6FY9e6PpJwcyEUfU0LxEoUECRQXLADdeSR+BGQdVaiegqcX+hypCUHFOVOLlmug19SUuLtDjXvTpYxp1y7NJLxs6ttW3MyJXfccUfIYjvXtuCdLoKpInWGUmBlJZN7sZ4rgRFNg9NJ1t/debZqmQ15GOjZrAiExxxzjLe8hgartAh3MM9EefbEso11h2+ytinyDYFEI4CilWg1Qn4SjoAsOM4V5cILL2yzEK8yq9FThY+WaD0sdYoCxSlaTpFyboM6RoqO+635WXJ/0UKxsZDx48d7nRNd6+yzz7avv/66zWUV2vv666/3tmkxZhc85I9//KNnldMaWZdffnmbkXopo1ozS5YwRXDUWkWB4ix1LnhA4D6+x46AFt6W4iQrq0JhBypbmtfhwrsfccQRrUFZnDKhMOSLFi1qzayUAS0FoIhvyS5dbdta5FzWbN0Tf/vb39pg0KLe//znP9tscz/0PJHboQZadA8GLvasxdUVmVTrLuk5IUXCb9LVZ6tbi0o89GzS0gASRR/UoJDmu6kuA8UNbsnqGM+2Gss21lW+gdz4DgEIdI8Ailb3+HF2ihBQh0juQZqHIivNgQce6L3gtW6OIgtq/oXcNPSiDxaNWstq5UZYnWLljnPug/otq5GLhub29+SnXvoukqDWFVLHWp07KXsK3qFJ6hpJV8fcidzOdJ6Uwquuusqz0MmFR4urqjOuxUAVheu5555bL9jCxhtv7CWjjrzmsmhxVyT2BKQUaB05zftRHcqVVR19tW1ZWaWA6VNKmBOFKJf1QBZL7ZPlVe1ECrXcahUqPtmlq21bbVnWbg1G6N5QqHopAFJAxUmh5ANdih0nDcpIMRNXLSiu+0cDFVLcdI7mbklUR5tssok7zVefnX22ygVTzxrXDt0yGYIiV2X3TFHod83ZcjJu3DjvqwYJ1GZVZ25tQHdMLD5j3cY6yzcWDLgGBFKJAIpWKtU2Ze0yAVliNI9KgS00Ai1XO7nOffLJJ14nSR2jF198MaSSJIVkn3328a6tc53blstMoKIVzUWKXfqRPjUPRFERtciqRs2lHGkyuRZIVedbC8hqseJg0fGyeKnDrU62FlZVR1NpaD0bpRO4Jpk7Xwu76hwdp7k/7UVac+fxGX0CmoOl4CxaamDWrFkm11a5DKq9SqmShdVZAXR1WQ0UuEUusnL91P2gaJmag6hj2wvmEP0S9EyKXW3b22+/vacYqQOvtZL0fNA9Ii5atiFcMAtZfcVRAzZSAuRm+NBDD3lLPkg50O/TTz+9ZwqbAKl29tkqK7ushOIpl0EpqYEihV9rJMpKq3bs1jXUIJYWNJbFSwNjev7Ey901lm2ss3wDWfIdAhDoPoG0ysrKlu4nQwoQSC0CCm6hl7SsTxp51iTnZBd1TOQ2poiB6lQHdrIjlU1WL3XUxcIFWYh0vPbJ3Uxrh2kEOlwHtL002B89AnL5VB2qHcvC2V57duuqSRGIRzjt6JU8ckpdaduyuGjeoxgpSIMGVzoqch3UwIVc2/RcUch7DUqkkvT0s1XPObkeynXWzTuMJ99Yt7Ge5htPllwbAolIAEUrEWuFPEEAAhCAAAQgAAEIQAACSU0A18Gkrj4yDwEIQAACEIAABCAAAQgkIgH/rYCYiJTJEwS6SEBzwiItBBsuWc0D04RxBALJSoC2n6w1lzz5po0lT12RUwgkKwEUrWStOfKdEgQUVEILcnZWFKwARauz1Dg+kQjQ9hOpNvyZF9qYP+uVUkEgkQgwRyuRaoO8QAACEIAABCAAAQhAAAK+IMAcLV9UI4WAAAQgAAEIQAACEIAABBKJAIpWItUGeYEABCAAAQhAAAIQgAAEfEEgU2tKIBCAAAQgAAEIQAACEIAABCAQPQJYtKLHkpQgAAEIQAACEIAABCAAAQh4BFC0aAgQgAAEIAABCEAAAhCAAASiTABFK8pASQ4CEIAABCAAAQhAAAIQgACKFm0AAhCAAAQgAAEIQAACEIBAlAmgaEUZKMlBAAIQgAAEIAABCEAAAhBA0aINQAACEIAABCAAAQhAAAIQiDIBFK0oAyU5CEAAAhCAAAQgAAEIQAACKFq0AQhAAAIQgAAEIAABCEAAAlEmgKIVZaAkBwEIQAACEIAABCAAAQhAAEWLNgABCEAAAhCAAAQgAAEIQCDKBFC0ogyU5CAAAQhAAAIQgAAEIAABCKBo0QYgAAEIQAACEIAABCAAAQhEmQCKVpSBkhwEIAABCEAAAhCAAAQgAAEULdoABCAAAQhAAAIQgAAEIACBKBNA0YoyUJKDAAQgAAEIQAACEIAABCCAokUbgAAEIAABCEAAAhCAAAQgEGUCKFpRBkpyEIAABCAAAQhAAAIQgAAEMltaWqAAAQhAAAIQgAAEIAABCEAAAlEkgEUrijBJCgIQgAAEIAABCEAAAhCAgAigaNEOIAABCEAAAhCAAAQgAAEIRJkAilaUgZIcBCAAAQhAAAIQgAAEIAABFC3aAAQgAAEIQAACEIAABCAAgSgTQNGKMlCSgwAEIAABCEAAAhCAAAQggKJFG4AABCAAAQhAAAIQgAAEIBBlAihaUQZKchCAAAQgAAEIQAACEIAABFC0aAMQgAAEIAABCEAAAhCAAASiTABFK8pASQ4CEIAABCAAAQhAAAIQgACKFm0AAhCAAAQgAAEIQAACEIBAlAmgaEUZKMlBAAIQgAAEIAABCEAAAhBA0aINQAACEIAABCAAAQhAAAIQiDIBFK0oAyU5CEAAAhCAAAQgAAEIQAACKFq0AQhAAAIQgAAEIAABCEAAAlEmgKIVZaAkBwEIQAACEIAABCAAAQhAAEWLNgABCEAAAhCAAAQgAAEIQCDKBFC0ogyU5CAAAQhAAAIQgAAEIAABCKBo0QYgAAEIQAACEIAABCAAAQhEmUBmS0tLlJMkOQhAAAIQgAAEIAABCEAAAqlNIOPCCy+8LFURvPbaa/bJJ5/Yl19+2em/+vp6GzhwoG/RzZ4922pqaqy4uLjdMr7zzjv25ptvejwKCwvbPb4jBzz55JN21FFHWVlZmU2ZMqUjp8T9mLPOOsuuu+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"
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/kl5lkKlwQa1DadkKaPaJouBRIML0ZJQbTAwbVlR1Q432GADk0uWuz8Cj+nKdw0eyG0ssJ3KkieLrOT9999vTbarbVsDM4qmqQGMQCVLCf/85z/37rnWiwR8ERO5aMoCpu9OydIhUhLuuusub5BEikSwe3JAMgn1tTO8u/ps1QCYXOFk9Z89e7an3OpTipTkiiuu8KxWsQLTmTLHso11lW+suHEdCKQCARStVKhlyrgeASkach0MlhEjRrRu0oiy5NNPP/U6Ufn5+a3KU+tBP35Rx02ioBrO3Urzl+SSJV98zQdzImuaru/msrz55ptulzfCrkn06kDIjS9aItfIYFEwD43IqmMr61kocYqW5rKoIyNReSQaVXYWP2/Dj//k/uQsBMFuPYHH8T1+BD7//HPv4ppPF6iAuBypbjWC7urabe/OZ6g2GJie3Bada2ng9u5+10BIqHYqhVIiFzQnrrydbdtuEVxZtULJySefHGpz6yDLIYcc4rndBh+kwR/lX5Is91JneHf12SoecgWUlUoi91AptHLl07NMVq5YSmfKHMs21h2+seTHtSDgZwKZfi4cZYNAOAJypZNLW7D07du3dZObi6IOp0SdNc1jCSXOhUT7dLxGOGXd0ai8OkhycdE8jZUrV5o6uVq0d9dddzUpb+qkaeRRypXmjEn23nvvkB2vUNdub5vyUVxcvN5hcg2TaM5DOFGexET5lgVMx8raJ1HgkHCigAYSnYMkHgEp2RIp2aFE94bcPKMl4dpgYPqat9cTogAYocTd6+4+17ytrrRt3fsaHJEoSEMoCVc2N3jxxBNPhFWk3PPHfYZKP5G2dZS38uzK1Nlnqyuv5rJpUOf++++3r776yjQX9NZbb3W7Y/bZ0TLHuo11l2/MAHIhCPiYAIqWjyuXooUnoAnRHRVNbpfIwqX5WO3JggULWt3wNLoqRUtzVKRoSeFSx0xKljqzslopzbffftsLTNATboOaFB5KXLmkdEYSRWiToqUgGvpzHdNI5+kciY5HEo+AAqRIXD31dA7DtcHA60ZqT4HHdfa73Fg7Il1t2wp446zf4XjqeSNXQHec8qPvmiMn0WCLs4qFy6u7X8PtT5TtHeWt/LoydeXZ6sqruYZStCRSaHv16uV2xeyzo2WOdRuLBt+YQeRCEPApARQtn1YsxYoeARcZT2GoNXG+PQm0HmmeluZvuXlZchuUODcqKVxStDRPS+4nciPUPA0Fn4iWhHKbUtqu86vACJHEhfmWdUtWDqUnZVHnac5XKHHnyI0QSTwCatPq9EmB7qwo4EMocUpDqH3h2mDgsR05JvD4aH/vatvWeepoK6CF7olQVkJFfnMBcFy+pXg55UuRCRUBMZIooqffpDvPVrGQm7YC80jkjq1AP5p3KtfPRJRYt7Hu8k1EhuQJAslGgDlayVZj5DfmBJyLnFzt5G6kl1fwn1yj5Baiz8DAAhphVYhndWrl2iJFSvs12V8iRUsiRUvWLoW0VtRCdcB6Wpw7k3NfCnW9srKy1vllcsvRnBF9SpxbSqjz3D4XUjnUMWyLHwGt7yaR9TWUSDGQS5bWKXJrTblADWrnoUTLHCSzdLVtS0HU2lcS53oYzEFLQoRSUN09qHoIfqa435q3JhdjDXT4TbrzbBULRagUWwUTUah3iYJNaK5sIkqs21h3+SYiQ/IEgWQjgKKVbDVGfmNOQNH1FDBAk+YVqjmUKISu5iVpxFKuRIHiAk0o9LA6VIpaqI6TRFEPpbzJlevuu+/2trlohYFp9MR3rXWlTqIULWdxC76OyiWRlc6FY9e6PpJwcyEUfU0LxEoUECRQXLADdeSR+BGQdVaiegqcX+hypCUHFOVOLlmug19SUuLtDjXvTpYxp1y7NJLxs6ttW3MyJXfccUfIYjvXtuCdLoKpInWGUmBlJZN7sZ4rgRFNg9NJ1t/debZqmQ15GOjZrAiExxxzjLe8hgartAh3MM9EefbEso11h2+ytinyDYFEI4CilWg1Qn4SjoAsOM4V5cILL2yzEK8yq9FThY+WaD0sdYoCxSlaTpFyboM6RoqO+635WXJ/0UKxsZDx48d7nRNd6+yzz7avv/66zWUV2vv666/3tmkxZhc85I9//KNnldMaWZdffnmbkXopo1ozS5YwRXDUWkWB4ix1LnhA4D6+x46AFt6W4iQrq0JhBypbmtfhwrsfccQRrUFZnDKhMOSLFi1qzayUAS0FoIhvyS5dbdta5FzWbN0Tf/vb39pg0KLe//znP9tscz/0PJHboQZadA8GLvasxdUVmVTrLuk5IUXCb9LVZ6tbi0o89GzS0gASRR/UoJDmu6kuA8UNbsnqGM+2Gss21lW+gdz4DgEIdI8Ailb3+HF2ihBQh0juQZqHIivNgQce6L3gtW6OIgtq/oXcNPSiDxaNWstq5UZYnWLljnPug/otq5GLhub29+SnXvoukqDWFVLHWp07KXsK3qFJ6hpJV8fcidzOdJ6Uwquuusqz0MmFR4urqjOuxUAVheu5555bL9jCxhtv7CWjjrzmsmhxVyT2BKQUaB05zftRHcqVVR19tW1ZWaWA6VNKmBOFKJf1QBZL7ZPlVe1ECrXcahUqPtmlq21bbVnWbg1G6N5QqHopAFJAxUmh5ANdih0nDcpIMRNXLSiu+0cDFVLcdI7mbklUR5tssok7zVefnX22ygVTzxrXDt0yGYIiV2X3TFHod83ZcjJu3DjvqwYJ1GZVZ25tQHdMLD5j3cY6yzcWDLgGBFKJAIpWKtU2Ze0yAVliNI9KgS00Ai1XO7nOffLJJ14nSR2jF198MaSSJIVkn3328a6tc53blstMoKIVzUWKXfqRPjUPRFERtciqRs2lHGkyuRZIVedbC8hqseJg0fGyeKnDrU62FlZVR1NpaD0bpRO4Jpk7Xwu76hwdp7k/7UVac+fxGX0CmoOl4CxaamDWrFkm11a5DKq9SqmShdVZAXR1WQ0UuEUusnL91P2gaJmag6hj2wvmEP0S9EyKXW3b22+/vacYqQOvtZL0fNA9Ii5atiFcMAtZfcVRAzZSAuRm+NBDD3lLPkg50O/TTz+9ZwqbAKl29tkqK7ushOIpl0EpqYEihV9rJMpKq3bs1jXUIJYWNJbFSwNjev7Ey901lm2ss3wDWfIdAhDoPoG0ysrKlu4nQwoQSC0CCm6hl7SsTxp51iTnZBd1TOQ2poiB6lQHdrIjlU1WL3XUxcIFWYh0vPbJ3Uxrh2kEOlwHtL002B89AnL5VB2qHcvC2V57duuqSRGIRzjt6JU8ckpdaduyuGjeoxgpSIMGVzoqch3UwIVc2/RcUch7DUqkkvT0s1XPObkeynXWzTuMJ99Yt7Ge5htPllwbAolIAEUrEWuFPEEAAhCAAAQgAAEIQAACSU0A18Gkrj4yDwEIQAACEIAABCAAAQgkIgH/rYCYiJTJEwS6SEBzwiItBBsuWc0D04RxBALJSoC2n6w1lzz5po0lT12RUwgkKwEUrWStOfKdEgQUVEILcnZWFKwARauz1Dg+kQjQ9hOpNvyZF9qYP+uVUkEgkQgwRyuRaoO8QAACEIAABCAAAQhAAAK+IMAcLV9UI4WAAAQgAAEIQAACEIAABBKJAIpWItUGeYEABCAAAQhAAAIQgAAEfEEgU2tKIBCAAAQgAAEIQAACEIAABCAQPQJYtKLHkpQgAAEIQAACEIAABCAAAQh4BFC0aAgQgAAEIAABCEAAAhCAAASiTABFK8pASQ4CEIAABCAAAQhAAAIQgACKFm0AAhCAAAQgAAEIQAACEIBAlAmgaEUZKMlBAAIQgAAEIAABCEAAAhBA0aINQAACEIAABCAAAQhAAAIQiDIBFK0oAyU5CEAAAhCAAAQgAAEIQAACKFq0AQhAAAIQgAAEIAABCEAAAlEmgKIVZaAkBwEIQAACEIAABCAAAQhAAEWLNgABCEAAAhCAAAQgAAEIQCDKBFC0ogyU5CAAAQhAAAIQgAAEIAABCKBo0QYgAAEIQAACEIAABCAAAQhEmQCKVpSBkhwEIAABCEAAAhCAAAQgAAEULdoABCAAAQhAAAIQgAAEIACBKBNA0YoyUJKDAAQgAAEIQAACEIAABCCAokUbgAAEIAABCEAAAhCAAAQgEGUCKFpRBkpyEIAABCAAAQhAAAIQgAAEMltaWqAAAQhAAAIQgAAEIAABCEAAAlEkgEUrijBJCgIQgAAEIAABCEAAAhCAgAigaNEOIAABCEAAAhCAAAQgAAEIRJkAilaUgZIcBCAAAQhAAAIQgAAEIAABFC3aAAQgAAEIQAACEIAABCAAgSgTQNGKMlCSgwAEIAABCEAAAhCAAAQggKJFG4AABCAAAQhAAAIQgAAEIBBlAihaUQZKchCAAAQgAAEIQAACEIAABFC0aAMQgAAEIAABCEAAAhCAAASiTABFK8pASQ4CEIAABCAAAQhAAAIQgACKFm0AAhCAAAQgAAEIQAACEIBAlAmgaEUZKMlBAAIQgAAEIAABCEAAAhBA0aINQAACEIAABCAAAQhAAAIQiDIBFK0oAyU5CEAAAhCAAAQgAAEIQAACKFq0AQhAAAIQgAAEIAABCEAAAlEmgKIVZaAkBwEIQAACEIAABCAAAQhAAEWLNgABCEAAAhCAAAQgAAEIQCDKBFC0ogyU5CAAAQhAAAIQgAAEIAABCKBo0QYgAAEIQAACEIAABCAAAQhEmUBmS0tLlJMkOQhAAAIQgAAEIAABCEAAAqlNIOPCCy+8LFURvPbaa/bJJ5/Yl19+2em/+vp6GzhwoG/RzZ4922pqaqy4uLjdMr7zzjv25ptvejwKCwvbPb4jBzz55JN21FFHWVlZmU2ZMqUjp8T9mLPOOsuuu+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"
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
--------------------------------------------------------------------------------