markdown 算法,请注意

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 算法,请注意相关的知识,希望对你有一定的参考价值。

## Chapter1
二分查找, 时间复杂度 O(log<sup>n</sup>)
顺序查找, 时间复杂度 O(n)

二分查找实现:
```
In [50]: def binary_search(list, guess):
    ...:     low = 0
    ...:     high = len(list) -1
    ...:     while low<=high:
    ...:         mid = int((low+high)/2) # 中位向下取整
    ...:         item = list[mid]
    ...:         if item == guess:
    ...:             return mid
    ...:         if item < guess: # 中值小于猜测值, 提下限
    ...:             low = mid + 1
    ...:         else:
    ...:             high = mid - 1  # 中值大于猜测值, 缩上限
    ...:      return None

In [51]: index = binary_search(a, 7)

In [52]: index
Out[52]: 7

In [53]: index = binary_search(a, 84)

In [54]: index
Out[54]: 84
```

常见大 O 运行时间:
* O(log<sup>n</sup>) 对数时间
* O(n) 线性时间
* O(n*log<sup>n</sup>) 同快速排序
* O(n<sup>2</sup>) 
* O(n!) 

## Chapter2
内存就像抽屉盒
数组和链表的区别:
+ 数组擅长读取, 链表擅长插入删除
+ 数组内存连续, 链表不连续
+ 读取速度对比, 数组O(1), 链表O(n)
+ 插入删除速度对比, 数组O(n), 链表O(1)

选择排序, 时间复杂度 O(n<sup>2</sup>)
```
In [55]: def findSmallest(arr):
    ...:     smallest = arr[0]
    ...:     smallest_index = 0
    ...:     for i in range(1, len(arr)):
    ...:         if arr[i] < smallest:
    ...:             smallest = arr[i]
    ...:             smallest_index = i
    ...:     return smallest_index
    ...:

In [56]: def selectionSort(arr):
    ...:     newArr = []
    ...:     for i in range(len(arr)):
    ...:         smallest = findSmallest(arr)
    ...:         newArr.append(arr.pop(smallest))
    ...:     return newArr
    ...:

import numpy as np

In [57]: testArr = np.random.randint(10, size=20)
In [60]: selectionSort(testArr)
Out[60]: -----> sorted list
```
PS: 对数组操作时, 操作下标更方便

## Chapter3
递归要点:
1. 确定基线条件
2. 确定递归条件

e.g. impl of countdown function
```
In [1]: def countdown(num):
   ...:     print(num)
   ...:     if num == 0:  # 基线条件
   ...:         return
   ...:     else:
   ...:         countdown(num-1) 
   ...:
```

优点: 递归不一定效率高, 但是逻辑会更清晰
缺点: 占内存
解决方案: 
1. 用循环
2. 尾递归 (查下实现)
3. lazy 模式怎么样

## Chapter4
分而治之: divide and conquer (D&C), 一种递归思想
```
e.g. 168*64 的长方形, 计算出分割出来的最大正方形
In [22]: def getSquare(len, wid):
    ...:     if len % wid == 0:
    ...:         return wid
    ...:     else:
    ...:         ret = len%wid
    ...:         len = wid
    ...:         wid = ret
    ...:         return getSquare(len, wid)
    ...:
    ...:

In [23]: getSquare(164, 64)
Out[23]: 4
```
e.g. 使用递归计算数组加和
```
In [24]: def sum(arr):
    ...:     if len(arr) == 1:
    ...:         return arr[0]
    ...:     else:
    ...:         return arr.pop(0) + sum(arr)
    ...:

In [25]: sum([1,2,3])
Out[25]: 6
```
e.g. 快速排序实现
```
快速排序结合和归纳证明和 D&C 的思想方法, 有点绕, 但是很厉害的样子。 时间复杂度平均为 O(n*logn), 很优秀, 最糟糕时 O(log<sup>n</sup>)
In [28]: def quicksort(arr):
    ...:     if len(arr) < 2:
    ...:         return arr
    ...:     else:
    ...:         pivot = arr[0]
    ...:         less = [i for i in arr[1:] if i < pivot]
    ...:         greater = [i for i in arr[1:] if i > pivot]
    ...:         return quicksort(less) + [pivot] + quicksort(greater)
    ...:

In [29]: import numpy as np

In [30]: arr = np.random.randint(20, size=20)

In [31]: arr
Out[31]:
array([ 7,  5, 18, 17, 12, 18, 10,  0,  2,  5, 18, 12,  9,  0,  6, 14, 14,
       17, 13,  0])

In [32]: quicksort(arr)
Out[32]: [0, 2, 5, 6, 7, 9, 10, 12, 13, 14, 17, 18]
```

快速排序(quick sort) VS 合并排序(merge sort)
1. 平时我们讨论算法时间复杂度时是忽略常亮的
2. 快速排序的时间常量小于合并排序
3. 快速排序效率取决于你使用的基准值
    * 最糟糕的类似有序数组那第一个数字做基准 O(log<sup>n</sup>)
    * 最优的类似有序数组, 中值做基准 O(n * log n)
    
## Chapter5
散列表 - hash table - map, dict

决定散列表好坏的因素:

	1. 较低的填装因子, 填装因子>0.7, 扩容
	2. 良好的散列函数



优秀的散列表相当于集数组链表优势于一身, 差的散列表就是集两者缺点于一身

## Chapter6
广度优先搜索(breadth-first search BFS), 用于计算最短距离, 各种意义上的

图 = 节点 + 边
BFS: 用于图的查找算法, 解决两方面问题,

	1. 冲节点A 出发, 有前往B的路径吗
	2. 冲A出发, 前往B的最短路径



搜索效果怎么都感觉和那个什么 六度分隔理论 很像
图通过dict 实现

BFS 算法实现:
使用dict 存储友人关系, 通过队列存储搜索对象, 先从维度为1的查找, 如果1中没有, 把1中对象背后的2维度关系加入队列
```
In [38]: graph = {}

In [39]: graph['you'] = ['alice', 'bob', 'clark']

In [40]: graph['bob'] = ['anuj', 'peggy']

In [41]: graph['alice'] = ['peggy']

In [42]: graph['clark'] = ['thom', 'jonny']

In [43]: graph['anuj'] = []

In [44]: graph['peggy'] = []

In [45]: graph['thom'] = []

In [46]: graph['jonny'] = []

In [47]: from collections import deque
In [71]: def BFS():
    ...:     searched = []
    ...:     queue = deque(graph['you'])
    ...:     while queue:
    ...:         person = queue.popleft()
    ...:         if not person in searched:
    ...:             if isSeller(person):
    ...:                 return person
    ...:             else:
    ...:                 searched.append(person)
    ...:                 queue.extend(graph[person])
    ...:
    ...:     print('No such friend')
    ...:
In [72]: BFS()
Out[72]: 'thom'
```
时间复杂度 O(V+E), V:定点数, E: 边数

以上是关于markdown 算法,请注意的主要内容,如果未能解决你的问题,请参考以下文章

简体中国版文档的Markdown语法

Markdown规则

markdown常用语法

使用 Markdown,如何将图像及其标题居中?

MarkDown快捷键学习笔记

2021-11-07:奇偶链表。给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。请尝试使用原地算法完成。你的算法