Skip to content

Commit

Permalink
Merge pull request algorithm004-04#1016 from xxd/master
Browse files Browse the repository at this point in the history
049-week 07
  • Loading branch information
Daisy3485 authored Dec 3, 2019
2 parents 07038ee + 1303eea commit a2d0219
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 15 deletions.
10 changes: 6 additions & 4 deletions Week 01/id_049/NOTE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# NOTE



数组:缺点需要连续内存,插入和删除元素要额外操作O(n)
跳表:通过构建多级索引,提高检索速度。与红黑树比较,优势在于区间查找,代码更易实现
* N个节点跳表,每2个节点抽取一个索引,跳表整体高度h=log2n,每层遍历节点数m=3,所以查询时间复杂度O(logn)为啥 redis 使用跳表(skiplist)而不是使用 red-black? - 知乎 https://www.zhihu.com/question/20202931
链表:不需要连续内存空间,使用指针链接,分为单链表、双链表、循环链表、双向循环链表
五毒神掌用了一周下来,确实有很大改善,每题连续三天每天写一遍,这样基本不再会做完一道忘记一道了。
第一周最大收获是能够使用双指针和左右扫描,但是这周还是比较慢,第四课的链表刷的不多,看了下下周的内容估计只能整个上完之后重刷了
32 changes: 30 additions & 2 deletions Week 02/id_049/NOTE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
# NOTE
本周主要练习两大块内容哈希和递归
哈希总结就是把暴力法中的一层的O(n)优化成O(1),一种很常见的升维、以空间换时间的思维
递归就是把一个大问题拆分成各个子问题,推导出递推公式找到边界条件
树的面试题解法一般都是递归,为什么?
递归用于:1.问题可以分解成若干个重复子问题,2.问题和子问题可以用相同解法,3.有明确的终止条件;树型结构符合这一特点,整个树和部分树的结构相似度很高,所以逻辑清晰。树是一个非线性结构,使用广度优先方法进行遍历
递归模板
```python
def recursion(level, param1, param2, ...):
if level > MAX_LEVEL:
process_result
return
process(level,data)
self. recursion(level+1,p1 ...)


# reverse current level states if needed
```

```python
def divide_conuer(problem,p1,p2 ...):
if problem is None:
print result
return res
data = prepare_data(problem)
subproblems = split_problem(problem,data)
subresult1 = self.divide_conuer(subproblems[0], p1, ...)
subresult2 = self.divide_conuer(subproblems[2], p1, ...)
subresult3 = self.divide_conuer(subproblems[3], p1, ...)

result = process_result(subresult1,subresult2,subresult3)
# revert current level states if needed
```
本周作业基本完成,只是留给回溯和分治的时间太少了,等全部学完再继续刷题巩固
13 changes: 9 additions & 4 deletions Week 03/id_049/NOTE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# NOTE



深度优先搜索:visited保存访问过的节点,开始一条路走到头,再返回来走另一条路直到所有的几点都被访问
广度优先搜索:visited保存访问过的节点,queue来存每一层的node,每次pop出来放到visited,直到所有层都被访问
DFS和BFS处理二叉树基本掌握了,但是看到其他问题还是懵逼,找到个窍门就是先把公式写出来,然后慢慢套里边的情况
贪心算法:贪心有从前,后,中间某个位置开始贪心。如果贪心可以解出的一定就是最优解了,但是贪心很多时候并不能给出最优解,例如钱币兑换,图的最短路径等
贪心、回溯、动态规划的区别
1. 贪心:局部最优解
2. 回溯:回退
3. 动态规划:最优判断 + 回退
二分查找:窍门和DFS/BFS差不多就是先把公式写出来,然后慢慢套里边的情况。如果是半有序数组关键是找到开始旋转的下标,增加了个步骤。
12 changes: 9 additions & 3 deletions Week 05/id_049/NOTE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# NOTE


动态规划题的步骤

递推+记忆化:如果没思路就按照递推来做,再加上记忆
状态定义:opt[n], dp[n], fib[n]
状态转移方程:opt[n] = best_of(opt[n-1],opt[n-2],….)
最优子结构
如果找不出最优子结构的递推公式就只能递归尝试+不行回退=回溯
贪心:每一步全局最优解
DP是集以上两者之大成
所以DP的解法是找重复性,然后定义数组状态不行就生维,然后推出DP方程,自我感觉自底向上的思考方法是最容易的,比如62,63,64,72等题一个差不多的模板就能做出来
38 changes: 36 additions & 2 deletions Week 06/id_049/NOTE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,38 @@
# NOTE
## 第 13 课 | 字典树和并查集
1. Trie树的基本实现和特性
字典树,即Trie树,又称单词查找树或键树,是一种树形结构。典型应用是用于统计和排序大量的字符串,所以经常被搜索引擎系统用于文本词频统计。 它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 基本性质:
1. 结点本身不存完整单词;
2. 从根结点到某一结点,路径上经过的字符连接起来,为该结点对应的字符串;
3. 每个结点的所有子结点路径代表的字符都不相同。 字典树:26叉树。
Trie树的核心思想是空间换时间。 利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。


并查集是用来解决组团、配对的问题。例如:分析两个人是不是互为好友或者是否可以互看朋友圈。 执行操作,把a设置为b的朋友。 基本操作:
- makeSet(s):建立一个新的并查集,其中包含s个单元素集合。
- unionSet(x,y):把元素x和元素y所在的集合合并,要求x和y所在的集合不相交,如果相交则不合并。
- find(x):找到元素x所在的集合的代表,该操作也可以用于判断两个元素是否位于同一个集合,只要将它们各自的代表比较一下就可以了。

```
dx = [1, -1, 0, 0]
dy = [0, 0, -1, 1]
x, y = cur_positon
for I in range(4):
x + dx, y + dy
```
17,79,130,200一个套路

## 第 14 课 | 高级搜索
剪枝大概的加速方式1选项少的先做,2预处理

双向BFS思想就是,对比两个集合,头和尾,哪个元素少,就交换位置
```
if len(end) < len(begin):
end, begin = begin, end
```

A*过了一遍视频没学进去,估价函数比较复杂,准备学完后返回来好好看看

## 第 15 课 | 红黑树和AVL树
红黑树(Red Black Tree) 是一种自平衡二叉查找树,典型的用途是实现关联数组。从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。TreeSet的底层就是红黑树实现的。

这周信息量太大了,看了看下周的课表。。。。。。DP比起来真不算难了,期待高级DP
8 changes: 8 additions & 0 deletions Week 07/id_049/LeetCode_1122_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Solution:
def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
res = []
for i in arr2:
while i in arr1:
res.append(i)
arr1.remove(i)
return res+sorted(arr1)
21 changes: 21 additions & 0 deletions Week 07/id_049/LeetCode_146_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from collections import OrderedDict
class LRUCache(OrderedDict):
# 申请一个空间
def __init__(self, capacity):
self.capacity = capacity

# get如果没有返回-1,如果有返回并且移动到头部
def get(self, key):
if key not in self:
return - 1

self.move_to_end(key)
return self[key]

# put如果capacity里有放到头部,如果没有放到尾部,如果超过容量把最后一个移出去
def put(self, key, value):
if key in self:
self.move_to_end(key)
self[key] = value
if len(self) > self.capacity:
self.popitem(last = False)
10 changes: 10 additions & 0 deletions Week 07/id_049/LeetCode_190_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class Solution:
def reverseBits(self, n):
count = 32
res = 0
while count:
res <<= 1
res += n & 1
n >>= 1
count -= 1
return int(bin(res),2)
7 changes: 7 additions & 0 deletions Week 07/id_049/LeetCode_191_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Solution(object):
def hammingWeight(self, n):
res = 0
while n:
res += n & 1
n >>= 1
return res
3 changes: 3 additions & 0 deletions Week 07/id_049/LeetCode_231_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
return n != 0 and n & (n - 1) == 0
11 changes: 11 additions & 0 deletions Week 07/id_049/LeetCode_242_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t):
return False
s_hash = {}
t_hash = {}
for i in s:
s_hash[i] = s_hash.get(i, 0)+1
for j in s:
t_hash[j] = t_hash.get(j, 0)+1
return s_hash == t_hash
7 changes: 7 additions & 0 deletions Week 07/id_049/LeetCode_338_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Solution:
def countBits(self, num: int) -> List[int]:
dp = [0]
for i in range(1, num + 1):
dp.append(dp[i >> 1] + (i & 1))
return dp

23 changes: 23 additions & 0 deletions Week 07/id_049/LeetCode_493_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Solution(object):
def reversePairs(self, nums):
if not nums:
return 0
return self.merge_sort_count(nums, 0, len(nums)-1) #0-4

def merge_sort_count(self, nums, begin, end):
if begin == end:
return 0
mid = (end+begin) >> 1
count = 0
count += self.merge_sort_count(nums, begin, mid)#0-2
count += self.merge_sort_count(nums, mid+1, end)#3-4

i, j = begin, mid+1
while i <= mid and j <= end:
if nums[i] > nums[j]*2:
count += mid+1-i
j += 1
else:
i += 1
nums[begin:end+1] = sorted(nums[begin:end+1])
return count
16 changes: 16 additions & 0 deletions Week 07/id_049/LeetCode_52_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution:
def totalNQueens(self, n: int) -> int:
if n < 1:return 0
self.count = 0
self.dfs(n, 0, 0, 0, 0)
return self.count

def dfs(self, n, row, cols, pie, na):
if row >= n:
self.count += 1
return
bits = (~(cols|pie|na)) & ((1 << n) -1)
while bits > 0:
p = bits & -bits
self.dfs(n, row+1, cols|p, (pie|p)>>1, (na|p)<<1)
bits = bits & (bits - 1)
17 changes: 17 additions & 0 deletions Week 07/id_049/LeetCode_56_049.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
n = len(intervals)
left = intervals[0][0]
right = intervals[0][1]
res = []
for i in range(1, n):
if right >= intervals[i][0]:
if intervals[i][1] > right:
right = intervals[i][1]
else:
res.append([left, right])
left = intervals[i][0]
right = intervals[i][1]
res.append([left, right])
return res

0 comments on commit a2d0219

Please sign in to comment.