Skip to content

Commit f6cdc8f

Browse files
committed
小傅哥 | update
1 parent f410b74 commit f6cdc8f

9 files changed

+8
-8
lines changed

docs/notes/解题/两数之和.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ sum = 1 + 1 + n + 1+ n + n
4141
= n (忽略低阶梯)
4242
```
4343

44-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-00.png)
44+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-00.png)
4545

4646
---
4747

@@ -65,7 +65,7 @@ while (sum < n) {
6565
这回我们只看执行次数最多的,很明显这是一个 ```2 * 2 * 2 ··· n```,大于 n 跳出循环。
6666
那么我们使用函数;2^x = n,x = logn,就可以表示出整体的时间复杂度为 O(logn)
6767

68-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-07.png)
68+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-07.png)
6969

7070
好!结合这两个例子,相信你对时间复杂度已经有所理解,后面的算法题中就可以知道自己的算法是否好坏。
7171

@@ -104,7 +104,7 @@ class Solution {
104104

105105
先不考虑时间复杂度的话,最直接的就是双层```for```循环,用每一个数和数组中其他数做家和比对,如下;
106106

107-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-01.png)
107+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-01.png)
108108

109109
可以看到这样的时间复杂度是;n*(n-1) ··· 4*3、4*2、4*1,也就是O(n!),有点像九九乘法表的结构。
110110

@@ -127,15 +127,15 @@ public int[] twoSum(int[] nums, int target) {
127127

128128
**耗时:**
129129

130-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-02.png)
130+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-02.png)
131131

132132
- 对于这样的算法虽然能解决问题,但是并不能满足我们的需求,毕竟这个级别的时间复杂度下实在是太慢了。
133133

134134
### 思路2,单层循环
135135

136136
为了把这样一个双层循环简化为单层,我们最能直接想到的就事放到 Map 这样的数据结构中,方便我们存取比对。那么这样的一个计算过程如下图;
137137

138-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-03.png)
138+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-03.png)
139139

140140
- 这个过程的核心内容是将原来的两数之和改成差值计算,并将每次的差与 Map 中元素进行比对。如果差值正好存在 Map 中,那么直接取出。否则将数存入到 Map 中,继续执行。
141141
- 这个过程就可以将原来的双层循环改为单层,时间复杂度也到了 O(n) 级别。
@@ -157,7 +157,7 @@ public static int[] twoSum(int[] nums, int target) {
157157

158158
**耗时:**
159159

160-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-04.png)
160+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-04.png)
161161

162162
- 可以看到当我们使用 Map 结构的时候,整个执行执行用时已经有了很大的改善。但是你有考虑过```containsKey``````get``` 是否为 null 相比哪个快吗?
163163
- 这个算法已经很良好了,但是这个对 key 值的比对还是很耗时的,需要反复的对 map 进行操作,那么我们还需要再优化一下。
@@ -166,7 +166,7 @@ public static int[] twoSum(int[] nums, int target) {
166166

167167
如果说想把我们上面使用 Map 结构的地方优化掉,我们可以考虑下 Map 数据是如何存放的,他有一种算法是自身扩容 2^n - 1 & 元素,求地址。之后按照地址在进行存放数据。那么我们可以把这部分算法拿出来,我们自己设计一个数组结构,将元素进行与运算存放到我们自己定义的数组中。如下图;
168168

169-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-05.png)
169+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-05.png)
170170

171171
- 左侧是我们假定的入参```int[] nums```,32是我们设定的值,这个值的设定需要满足存放大小够用,否则地址会混乱。
172172
- 接下来我们使用 32 - 1,也就是二进制 ```011111```与每一个数组中的值进行与运算,求存放地址。
@@ -192,7 +192,7 @@ public static int[] towSum(int[] nums, int target) {
192192

193193
**耗时:**
194194

195-
![](http://niubility-algorithm.itstack.org/assets/img/2020/0001-06.png)
195+
![](http://niubility-algorithm.itstack.org/assets/img/2020/niubility-algorithm-0001-06.png)
196196

197197
- 出现0毫秒耗时,100%击败,这个不一定每次都这样,可能你试的时候不一样。得益于数据结构的优化使得这个算法的耗时很少。
198198

0 commit comments

Comments
 (0)