20211116_datawhale31期_leetcode刷题_0预习
作者:互联网
0 序言及预习
目录
来源
Datewhle31期__LeetCode 刷题 :
-
航路开辟者:杨世超
-
领航员:刘军
-
航海士:杨世超、李彦鹏、叶志雄、赵子一
-
开源电子书
https://algo.itcharge.cn
1 数据结构与算法
- 算法(Algorithm)*就是解决问题的方法或者过程
- 数据结构(Data Structure) 是数据的计算机表示和相应的一组操作。程序(Program) 则是算法和数据结构的具体实现。
目的 : 对于待解决的问题,我们追求的是:选择更加合适的「数据结构」,使用花费时间更少、占用空间更小的「算法」
关于算法和数据结构自己总结:
1 数据结构,我们可以按照数据的 「逻辑结构」 和 「物理结构来进行分类。
-
物理结构(Physical Structure):数据的逻辑结构在计算机中的存储方式。
计算机内有多种存储结构,采用最多的是这两种结构:顺序存储结构、链式存储结构。
关于逻辑和物理结构详情总结:
2 算法
-
算法 指的就是解决问题的方法。算法是一系列的运算步骤,这些运算步骤可以解决特定的问题。
-
算法拥有 5 个基本特性:输入、输出、有穷性、确定性、可行性。
-
算法追求的目标有 5 个:正确性、可读性、健壮性(对非法数据以及操作有较好的反应和处理)、所需运行时间更少(时间复杂度更低)、占用内存空间更小(空间复杂度更低)。
2 算法复杂度
- 算法复杂度(Algorithm complexity):在问题的输入规模为 n 的条件下,程序的时间使用情况和空间使用情况。
2.1 时间复杂度
时间复杂度(Time Complexity):在问题的输入规模为 n 的条件下,算法运行所需要花费的时间,可以记作为 T(n)。
我们将基本操作次数作为时间复杂度的度量标准。换句话说,时间复杂度跟算法中基本操作次数的数量正相关。
基本操作 :算法执行中的每一条语句。每一次基本操作都可在常数时间内完成。
- 由简单的数学知识可知, 时间复杂度可用O表示: T(n) = O(f(n)), 表示为随n增大, 算法执行时间的增长趋势跟 f(n)相同。 O是一种渐进符号, T(n)称作算法的 渐进时间复杂度(Asymptotic time complexity),简称为 时间复杂度。
「渐进符号」 实际上是专门用来刻画函数的增长速度的, 常忽略低阶幂、系数、常量不影响规模大时增长速率的部分, 常用 Θ , O , Ω \Theta, O, \Omega Θ,O,Ω表示渐进的: 上下限(夹逼准则), 上限, 下限.
- 作为算法只关心------上界.
- 求O的一般步骤:
- 找出算法中的基本操作(基本语句):算法中执行次数最多的语句就是基本语句,通常是最内层循环的循环体部分。
- 计算基本语句执行次数的数量级:只需要计算基本语句执行次数的数量级,即保证函数中的最高次幂正确即可。像最高次幂的系数和低次幂可以忽略。
- 用大 O 表示法表示时间复杂度:将上一步中计算的数量级放入 O 渐进上界符号中。
- 注意一些运算法则:
-
加法: 总的时间复杂度等于量级最大的基本语句的时间复杂度。
- 即: 如果
T
1
(
n
)
=
O
(
f
1
(
n
)
)
,
T
2
=
O
(
f
2
(
n
)
)
,
T
(
n
)
=
T
1
(
n
)
+
T
2
(
n
)
T_{1}(n)=O\left(f_{1}(n)\right) , T_{2}=O\left(f_{2}(n)\right), T(n)=T_{1}(n)+T_{2}(n)
T1(n)=O(f1(n)),T2=O(f2(n)),T(n)=T1(n)+T2(n) ,则
T ( n ) = O ( f ( n ) ) = max ( O ( f 1 ( n ) ) , O ( f 2 ( n ) ) ) = O ( max ( f 1 ( n ) , f 2 ( n ) ) ) 。 T(n)=O(f(n))=\max \left(O\left(f_{1}(n)\right), O\left(f_{2}(n)\right)\right)=O\left(\max \left(f_{1}(n), f_{2}(n)\right)\right) 。 T(n)=O(f(n))=max(O(f1(n)),O(f2(n)))=O(max(f1(n),f2(n)))。
- 即: 如果
T
1
(
n
)
=
O
(
f
1
(
n
)
)
,
T
2
=
O
(
f
2
(
n
)
)
,
T
(
n
)
=
T
1
(
n
)
+
T
2
(
n
)
T_{1}(n)=O\left(f_{1}(n)\right) , T_{2}=O\left(f_{2}(n)\right), T(n)=T_{1}(n)+T_{2}(n)
T1(n)=O(f1(n)),T2=O(f2(n)),T(n)=T1(n)+T2(n) ,则
-
乘法原则:循环嵌套代码的复杂度等于嵌套内外基本语句的时间复杂度乘积
- 如果 T 1 = O ( f 1 ( n ) ) , T 2 = O ( f 2 ( n ) ) , T ( n ) = T 1 ( n ) T 2 ( n ) T_{1}=O\left(f_{1}(n)\right), T_{2}=O\left(f_{2}(n)\right), T(n)=T_{1}(n) T_{2}(n) T1=O(f1(n)),T2=O(f2(n)),T(n)=T1(n)T2(n) , 则 T ( n ) = O ( f ( n ) ) = O ( f 1 ( n ) ) O ( f 2 ( n ) ) = O ( f 1 ( n ) f 2 ( n ) ) T(n)=O(f(n))=O\left(f_{1}(n)\right) O\left(f_{2}(n)\right)=O\left(f_{1}(n) f_{2}(n)\right) T(n)=O(f(n))=O(f1(n))O(f2(n))=O(f1(n)f2(n))
-
-
一些常见时间复杂度:
- O(1) : 不存在循环语句、递归语句
- O(n) : 含有非嵌套循环,且单层循环下的语句执行次数为 n 的算法涉及线性时间复杂度, 算法规模随n增大呈线性增长.
- O ( n 2 ) O(n^2) O(n2): 一般含有双层嵌套,且每层循环下的语句执行次数为 n 的算法涉及平方时间复杂度, 算法规模随n增大呈平方增长.
- O(n!) : 阶乘时间复杂度一般出现在与「全排列」相关的算法中。这类算法随着问题规模 n 的增大,对应计算次数呈阶乘关系增长。
- O ( l o g 2 n ) O(log_2n) O(log2n) : 对数时间复杂度一般出现在「二分查找」、「分治」这种一分为二的算法中。这类算法随着问题规模 n 的增大,对应的计算次数呈对数关系增长。
- O ( n l o g 2 n ) O(n log_2 n) O(nlog2n): 线性对数一般出现在排序算法中,例如「快速排序」、「归并排序」、「堆排序」等。这类算法随着问题规模 n 的增大,对应的计算次数呈线性对数关系增长
-
排序: 根据从小到大排序,常见的算法复杂度主要有: O ( 1 ) < O ( log 2 n ) < O ( n ) < O ( n log 2 n ) < O ( n 2 ) < O(1)<O\left(\log _{2} n\right)<O(n)<O\left(n \log _{2} n\right)<O\left(n^{2}\right)< O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)< O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O\left(n^{3}\right)<O\left(2^{n}\right)<O(n !)<O\left(n^{n}\right) O(n3)<O(2n)<O(n!)<O(nn)
- 最佳, 最糟, 平均时间复杂度:
- 最佳时间复杂度:每个输入规模下用时最短的输入所对应的时间复杂度。
- 最坏时间复杂度:每个输入规模下用时最长的输入所对应的时间复杂度。
- 平均时间复杂度:每个输入规模下所有可能的输入所对应的平均用时复杂度(随机输入下期望用时的复杂度)。----- 所有情况总和除以情况数量
2.2 空间复杂度
空间复杂度(Space Complexity):在问题的输入规模为 n 的条件下,算法所占用的空间大小,可以记作为 S(n)。一般将 算法的辅助空间 作为衡量空间复杂度的标准。
-
空间复杂度的函数可以表示为S(n) = O(f(n)) ,它表示的是随着问题规模 n 的增大,算法所占空间f(n)的增长趋势跟 相同。------------ 主要包括「局部变量(算法范围内定义的变量)所占用的存储空间」和「系统为实现递归(如果算法是递归的话)所使用的堆栈空间」两个部分。
-
排序:常见的算法复杂度主要有: O ( 1 ) < O ( log 2 n ) < O ( n ) < O ( n 2 ) < O ( 2 n ) O(1)<O\left(\log _{2} n\right)<O(n)<O\left(n^{2}\right)<O\left(2^{n}\right) O(1)<O(log2n)<O(n)<O(n2)<O(2n)
3 leetcode
-
推荐刷题顺序:
1.初级算法
2.数组类算法
3.数组和字符串
4.链表类算法
5.哈希表
6.队列 & 栈
7.递归
8.二分查找
9.二叉树
10.中级算法
11.高级算法
12.算法面试题汇总 -
自己LeetCode的第一题---------------两数之和:
- 暴力
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
size = len(nums)
for i in range(size):
for j in range(i + 1, size):
if nums[i] + nums[j] == target:
return [i,j]
return[]
2.哈希—字典:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
size = len(nums)
dic = {}
for i in range(size):
if target - nums[i] in dic:
return [i,dic[target - nums[i]]]
dic[nums[i]] = i # 没找到符合条件 使用字典存值及下标 省去再次遍历下次直接访问
return []
- 结果对比
标签:语句,20211116,right,datawhale31,复杂度,算法,时间,leetcode,left 来源: https://blog.csdn.net/yuliuchenyin/article/details/121353935