Leecode-每日一题
1. 刷题方法
要刷多少题?
- 每个类型的题目10-20题(动态规划多多益善)
- 总共200~300题
如何刷题?
-
同类型题目一起刷,总结相似与不同(白天刷新题,晚上复习旧题)
周一:树/链表/搜索/动态规划
周二:
周三:
周四:
周五:
周六:
周日: -
刷三遍
第一遍:五分钟想不出来看答案
第二遍:尝试不看答案完整实现(一道题不超过60min)
第三遍:3天后,尝试15-20分钟快速实现
- 看别人代码
看3-5种不同的实现,分析别人的代码优缺点,为什么速度快/慢?(leecode答案速度排名中间代码比较好,不要为了速度用一些奇怪的技巧优化)
学习新的语言/算法/数据结构/API/模板/最佳实践
- 刷题过程中培养的能力
扩宽的思路,至少能看出该使用什么样的算法
数据规模->实践复杂度推算
代码风格:1.一致性:命名/缩进/括号/换行 2.有意义的变量名
学习来源参考:bilibili花花酱
2. 时间&空间复杂度
2.1 时间复杂度
什么是时间复杂度?算法的执行效率,算法的执行时间与算法的输入值之间的关系
**大O表示法/常用复杂度/常用复杂度对比:**找循环,有循环不看其他– O ( 1 ) < O ( l o g N ) < O ( N ) < O ( N l o g N ) < O ( N 2 ) < O ( 2 N ) < O ( N ! ) ; O ( M + N ) O(1) < O(logN) < O(N) < O(NlogN) < O(N^2) < O(2^N) < O(N!) ; O(M+N) O(1)<O(logN)<O(N)<O(NlogN)<O(N2)<O(2N)<O(N!);O(M+N)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bL1R4RJ2-1627044177067)(F:\0. Note\Typora-image\latex\image-20210723150321726.png)]
# 1. O(1): 无循环, 一般是O(1)
def O1(num):
i = num
j = num*2
return i+j
# 2. O(N)
def ON(num):
total = 0
for i in range(num):
total += 1
return total
# 3. O(logN)
def OlogN(num):
i = 1
while (i<num): # 2^次数 = num; 次数=log2num
i = i*2
return i
# 4. O(M+N)
def OMN(num1, num2):
total = 0
for i in range(num1):
total += i
for j in range(num2):
total += j
return total
# 5. O(NlogN) / O(NlogM)
def ONlogN(num):
total = 0
j = 1
for i in range(num): # N
while(j<num): # logN
total += i + j
j = j*2
return total
# 6. O(N^2)
def On2(num):
total = 0
for i in range(num):
for j in range(num):
total = i + j
2.2 空间复杂度
什么是空间复杂度?算法存储空间与输入值之间的关系
占空间:找已经声明的变量、for语句不占空间
# 1. O(1) 变量是常量情况, 不随输入值改变
def test(num):
total = 0
for i in range(num):
total += i
return total
# 2. O(N) 有数组、递归stack
def test(num):
array = []
for num in nums:
array.append(num)
return array
常用空间复杂度: O ( 1 ) < O ( N ) < O ( N 2 ) O(1)<O(N)<O(N^2) O(1)<O(N)<O(N2) 用不上 O ( l o g N ) , O ( N l o g N ) O(logN), O(NlogN) O(logN),O(NlogN)
2.3 时间&空间
- 两者互斥,通常先考虑时间复杂度最低的
- 工作时:时间复杂度、空间复杂度各有一个最优,问选哪一种
3. 数据结构
3.1 数据结构-数组
3.1 知识点
数组:在连续的内存空间中,存储一组相同类型的元素
特点:读多写少——适合读,不适合写
区分:
- 元素和索引(相对位置,从0开始)
- 数组访问(Acess,a[1]) 数组搜索(Search,找到这个元素)
四种操作方式:
- 访问/读取Access:时间复杂度O(1)
- 搜索Search:最坏时间复杂度O(N)、二分法搜索
- 插入Insert:最坏时间复杂度O(N),每个后移一位
- 删除Delete:最坏时间复杂度O(N),每个前移一位
3.2 python数组常用操作
-
创建数组
-
添加元素,a.append()-O(1) a.insert(插入位置,元素)-O(1)~O(N)
-
访问元素,用索引/下标访问元素a[索引],O(1)
-
更新元素,a[要更新的索引位置] = 88,O(1)
-
删除元素,三种方法remove/pop
- a.remove(元素值) O(N)
- a.pop(索引) O(N)
- a.pop() 删除最后一个元素 O(1)
-
获取数组长度,len(a)
-
遍历数组,三种方法-O(N)
# 1. for i in a: print(i) # 2. for index, element in enumerate(a): print(index, element) # 3. for i in range(0, len(a)): print(i, a[i])
-
查找某个元素,a.index(元素) 返回元素所在的索引O(N)
-
数组排序 a.sort() 反序a.sort(reverse=True) O(NlogN)