时间复杂度:
!常数操作:一个操作如果跟数据量无关,每次都是固定时间内完成的操作,就叫做常数操作。
int a=1, b=2;
a+b//没有数据量的操作
list[1,2,3,4,5,6,7,8,9,0]
for(int i=0;i<list.Length;i++)
{
//数据量的操作
//数据长度就是操作次数
}
!时间复杂度就是在算法流程中,描述常数操作次数的表达式,用于估计算法运行时间的一个式子(单位),写作O(n),算法流程的好坏先看时间复杂度,再看不同样本下的实际运行时间(也叫常数项时间)。
重点**********多次循环中O(n)的次方必须都操作同组数据,复杂情况时根据算法执行过程判断。
print("hello")//O(1)执行一次
for(int i=0;i<list.Length;i++)//O(n)执行N次
{
print("hello")
}
for(int i=0;i<list.Length;i++) //O(n²)执行N次的平方
{
for(int j=0;j<i-1;j++)
{
print("hello")
}
}
for(int i=0;i<list.Length;i++) //O(n³)执行N次的立方
{
for(int j=0;j<i-1;j++)
{
for(int k=0;k<j-1;k++)
{
print("hello")
}
}
}
!不上升的数据量的操作时,始终属于O(1)
//执行三次,没有数据量的操作,始终是O(1)
print("hello")
print("hello")
print("hello")
//循环一次,常数操作多次。始终是O(n)
for(int i=0;i<list.Length;i++)
{
print("hello")
print("hello")
}
//循环二次,每次循环常数操作多次,始终属于O(n²)
for(int i=0;i<list.Length;i++)
{
print("hello")
print("hello")
for(int j=0;j<i-1;j++)
{
print("hello")
print("hello")
print("hello")
}
}
!当循环中出现折半的时候,复杂度式子中会出现logn,写作O(logn)
int i=64;
while(i>1)
{
print(i);
i=i/2;
}
//输出64,32,16,8,4,2,出现折半
!效率排序:
O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n²logn)<O(n³)
空间复杂度:
!空间复杂度是评估算法的内存占用大小的公式。它的表达式和时间复杂度完全相同。
!算法使用了多个变量:O(1)
!算法使用了一个长度为n的一维列表:O(n)
!算法使用了m行n列的二维列表:O(mn)
!算法使用了n行n列的二维列表:O(n²)
!实际算法使用中经常以空间换时间。因为用户的体验比内存占比更重要。