这周,起步比别人晚了一周,要尽量赶上。
首先是时间复杂度:
一条语句的频度是指该语句在算法中被重复执行的频率。而算法中所有语句的频度之和记做T(n),它是该算法问题规模 n 的函数,而时间复杂度主要就是分析 T(n) 的数量级。算法中基本运算(就是指最深层的循环内的语句)与T(n) 同数量级,所以通常采用算法中基本运算的频度 f(n) 来分析算法的时间复杂度。我们将 f(n) 中随 n 增长最快的项的系数置为1作为时间复杂度的度量。f(n) = a*n^3+b*n^2+c; 时间复杂度为O(n^3)(其中 'O' 的含义为时间复杂度数量级)。简而言之,就是描述程序运行的 速度是否快,程序占用的内存空间是否小。
例一:给小灰一条长16寸的面包,小灰每5天吃掉面包剩余长度的一半,第一次吃掉8寸,第二次吃掉4寸,第三次吃掉2寸......那么小灰把面包吃得只剩下1寸,需要多少天呢?
答:用数字16不断地除以2,直到等于1为止,这里要涉及到数学当中的对数,以2位底,16的对数,可以简写为log(2)16。因此,把面包吃得只剩下1寸,需要 5 X log(2)16 = 5 X 4 = 20 天。
如果面包的长度是 N 寸呢?需要 5 X logn = 5log(2)n天,记作 T(n) = 5log(2)n。
例二:
int aFunc(int n) {
for(int i = 0; i<n; i++) { // 需要执行 (n + 1) 次
printf("Hello, World!\n"); // 需要执行 n 次
}
return 0; // 需要执行 1 次
}
可以看出来 循环了需要执行n+1+n+1=2n+2次。
二分边界问题:
在学JAVA时 ,学习过这样的。比如,在(1,2,3,4,5,6,7,8,9,0,10)这是个数中,用二分法查找数字6。
public class Main{
public static void main(String[] args){
int arr[]={1,2,3,4,5,6,7,8,9,10};
int star=0;
int end=arr.length-1;
int canshu=-1;
int count=0;
int mb=6;
while(star<=end){
int mid=(star+end)/2;
if(arr[mid]==mb){
count++;
canshu=mid;
break;
else if(arr[mid]<mb){
star=mid+1;
else if(arr[mid]>mb){
end=mid-1;}
} } }
if(canshu=-1){
System.out.println("用二分法找到目标"+mb+",且位于第"+canshu+"个数组中"+",共循环了"+count+"次。");}
else{
System.out.println("没有找到目标函数");}
C++:
二分查找算法的基本思想:在有序表中,每次都取中间记录作为比较对象,若给定值与中间记录的关键字相等则查找成功,返回该关键字的索引;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上诉过程,直到查找成功,或者所有查找区域无记录,查找失败为止,返回一个值代表没有找到。