Skip to content

Commit 55412f1

Browse files
Merge pull request apachecn#20 from chenyyx/master
辛苦啦 瑶妹 | 添加 two_sum 的 solution 的 jupyter 版本
2 parents 37346cc + e5873b6 commit 55412f1

File tree

1 file changed

+251
-0
lines changed

1 file changed

+251
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# 1. Two Sum 两数之和\n",
8+
"\n",
9+
"## 题目:\n",
10+
"\n",
11+
" - https://leetcode.com/problems/two-sum/\n",
12+
" - https://leetcode-cn.com/problems/two-sum/description/\n",
13+
"\n",
14+
"```\n",
15+
"给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。\n",
16+
"\n",
17+
"你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。\n",
18+
"\n",
19+
"> 示例:\n",
20+
"\n",
21+
"给定 nums = [2, 7, 11, 15], target = 9\n",
22+
"\n",
23+
"因为 nums[0] + nums[1] = 2 + 7 = 9\n",
24+
"所以返回 [0, 1]\n",
25+
"```\n",
26+
"\n",
27+
"## 难度:Easy\n",
28+
"\n",
29+
"这个题目略微有点简单,我们只要注意的是,同样的元素不能被重复利用两次。\n",
30+
"\n",
31+
"还有就是思考,是不是我们可以使用一次循环就能够找到这两个数呢?\n",
32+
"\n",
33+
"接下来我们看一下如何解决这个问题。\n",
34+
"\n",
35+
"> 思路 1\n",
36+
"\n",
37+
" - 简单判断一下,是否两个数都在 list 中,以及判断两个数不是重复利用一个元素即可。"
38+
]
39+
},
40+
{
41+
"cell_type": "code",
42+
"execution_count": 1,
43+
"metadata": {},
44+
"outputs": [
45+
{
46+
"name": "stdout",
47+
"output_type": "stream",
48+
"text": [
49+
"[1, 2]\n"
50+
]
51+
}
52+
],
53+
"source": [
54+
"class Solution(object):\n",
55+
" def twoSum(self, nums, target):\n",
56+
" \"\"\"\n",
57+
" :type nums: List[int]\n",
58+
" :type target: int\n",
59+
" :rtype: List[int]\n",
60+
" \"\"\"\n",
61+
" # 循环名为 nums 的 list\n",
62+
" for num_one in nums:\n",
63+
" # 判断 target 减去 num_one 是否仍在我们的 nums list 中,另一个条件是这两个数不是同一个元素\n",
64+
" if target - num_one in nums and num_one is not target-num_one:\n",
65+
" # 返回两个数对应的 index\n",
66+
" return [nums.index(num_one), nums.index(target - num_one)]\n",
67+
" \n",
68+
"nums = [4, 3, 5, 15]\n",
69+
"target = 8\n",
70+
"s = Solution()\n",
71+
"print(s.twoSum(nums, target))"
72+
]
73+
},
74+
{
75+
"cell_type": "markdown",
76+
"metadata": {},
77+
"source": [
78+
"> 思路 2\n",
79+
"\n",
80+
" - 其实我们上一个解决方案已经是弄的一个 for 循环了,这次我们换一个思路。\n",
81+
" - 可以用 $O(n^2)$ 的循环(lookup)\n",
82+
" - 其实也可以牺牲空间换取时间,异常聪明的 AC 解法\n",
83+
" \n",
84+
"```\n",
85+
" 2 7 11 15\n",
86+
" 不存在 存在之中 \n",
87+
"lookup {2:0} [0, 1]\n",
88+
"```\n",
89+
"大体思路如下:\n",
90+
"\n",
91+
" - 建立字典 lookup 存放第一个数字,并存放该数字的 index\n",
92+
" - 判断 lookup 中是否存在: target - 当前数字, 则表面 当前值和 lookup中的值加和为 target\n",
93+
" - 如果存在,则返回: target - 当前数字 的 index 和 当前值的 index"
94+
]
95+
},
96+
{
97+
"cell_type": "code",
98+
"execution_count": 2,
99+
"metadata": {},
100+
"outputs": [
101+
{
102+
"name": "stdout",
103+
"output_type": "stream",
104+
"text": [
105+
"[1, 2]\n"
106+
]
107+
}
108+
],
109+
"source": [
110+
"class Solution(object):\n",
111+
" def twoSum(self, nums, target):\n",
112+
" \"\"\"\n",
113+
" :type nums: List[int]\n",
114+
" :type target: int\n",
115+
" :rtype: List[int]\n",
116+
" \"\"\"\n",
117+
" # 创建 lookup 字典\n",
118+
" lookup = {}\n",
119+
" # 使用 enumerate 语法,返回的是每一个元素及其对应的 index\n",
120+
" for i, num in enumerate(nums):\n",
121+
" if target - num in lookup:\n",
122+
" return [lookup[target - num],i]\n",
123+
" lookup[num] = i\n",
124+
" return []\n",
125+
" \n",
126+
"nums = [4, 3, 5, 15]\n",
127+
"target = 8\n",
128+
"s = Solution()\n",
129+
"print(s.twoSum(nums, target))"
130+
]
131+
},
132+
{
133+
"cell_type": "markdown",
134+
"metadata": {},
135+
"source": [
136+
"> 思路 3\n",
137+
"\n",
138+
" - 对于 dict ,也就是其他语言的 map,判断一个元素在不在容器中,list 要遍历,而 set 和 dict 直接根据哈希算出,不需要遍历\n",
139+
" - 我们可以仿照上面的代码,但是换个简单的写法。\n",
140+
" - 对于字典的这种方式,如果我们只是判断 i 以及 target - i 是不是相等,这样是错误的,如果两个元素相同,但是不是同一个元素,那就会出错了。\n",
141+
" \n",
142+
"比如,我们先看一下错误的版本:"
143+
]
144+
},
145+
{
146+
"cell_type": "code",
147+
"execution_count": 3,
148+
"metadata": {},
149+
"outputs": [
150+
{
151+
"name": "stdout",
152+
"output_type": "stream",
153+
"text": [
154+
"None\n"
155+
]
156+
}
157+
],
158+
"source": [
159+
"class Solution:\n",
160+
" def twoSum(self, nums, target):\n",
161+
" \"\"\"\n",
162+
" :type nums: List[int]\n",
163+
" :type target: int\n",
164+
" :rtype: List[int]\n",
165+
" \"\"\"\n",
166+
" dict1 = {}\n",
167+
" for k, i in enumerate(nums):\n",
168+
" dict1[i] = k\n",
169+
" if target - i in dict1 and i is not target - i:\n",
170+
" return [dict1[target - i], dict1[i]]\n",
171+
"\n",
172+
"nums = [3, 3]\n",
173+
"target = 6\n",
174+
"s = Solution()\n",
175+
"print(s.twoSum(nums, target))"
176+
]
177+
},
178+
{
179+
"cell_type": "markdown",
180+
"metadata": {},
181+
"source": [
182+
"上面的代码是存在问题的,对于相同的元素 [3, 3], target =6, 就得到了 None ,按理说,应该得到 [0, 1] 的。所以,这地方的判断是错误的。\n",
183+
"\n",
184+
" - 对于字典的那种方式,就只能索引为 key,数据为value,只是这样一来,判断在或者不在,还是多了一层循环\n",
185+
" \n",
186+
"下面的版本是正确的版本:"
187+
]
188+
},
189+
{
190+
"cell_type": "code",
191+
"execution_count": 5,
192+
"metadata": {},
193+
"outputs": [
194+
{
195+
"name": "stdout",
196+
"output_type": "stream",
197+
"text": [
198+
"[0, 1]\n"
199+
]
200+
}
201+
],
202+
"source": [
203+
"class Solution:\n",
204+
" def twoSum(self, nums, target):\n",
205+
" \"\"\"\n",
206+
" :type nums: List[int]\n",
207+
" :type target: int\n",
208+
" :rtype: List[int]\n",
209+
" \"\"\"\n",
210+
" for k, i in enumerate(nums):\n",
211+
" if target - i in nums[k + 1:]:\n",
212+
" return [k, nums[k + 1:].index(target - i) + k + 1]\n",
213+
"\n",
214+
"nums = [3, 3]\n",
215+
"target = 6\n",
216+
"s = Solution()\n",
217+
"print(s.twoSum(nums, target)) "
218+
]
219+
},
220+
{
221+
"cell_type": "markdown",
222+
"metadata": {},
223+
"source": [
224+
"## 小结\n",
225+
"\n",
226+
"应该还有更加好的解法,大佬们积极贡献自己的解法哈。一起为好的工作,好的未来,加油。"
227+
]
228+
}
229+
],
230+
"metadata": {
231+
"kernelspec": {
232+
"display_name": "Python 3",
233+
"language": "python",
234+
"name": "python3"
235+
},
236+
"language_info": {
237+
"codemirror_mode": {
238+
"name": "ipython",
239+
"version": 3
240+
},
241+
"file_extension": ".py",
242+
"mimetype": "text/x-python",
243+
"name": "python",
244+
"nbconvert_exporter": "python",
245+
"pygments_lexer": "ipython3",
246+
"version": "3.6.3"
247+
}
248+
},
249+
"nbformat": 4,
250+
"nbformat_minor": 2
251+
}

0 commit comments

Comments
 (0)