算法入门第一课

孤人 提交于 2020-02-05 02:24:37

算法入门第一课
题目一:
时间复杂度(粗描):
1)常数时间复杂度:
不看系数,只要高阶,不要低阶。
2)评价一个流程的好坏:
先看时间复杂度的指标,然后在分析不同数据样本的实际运行时间,也就是“常数时间项”。
在相同时间复杂度的情况下,大量数据进行比较是十分重要的。

题目二:
选择排序,冒泡排序细节的讲解与复杂度分析
额外空间复杂度(用完可以释放的空间):
时间复杂度O(n^2) 额外空间复杂度O(1),与数据状况无关
选择排序:依次选择最小的和前面交换。
冒泡排序:最大的数向后排。

题目三:
插入排序:00有序,01有序,0~2有序,…挨着交换
时间复杂度:最坏的时候O(n^2):最好O(n) 额外空间复杂度O(1),与数据状况有关。

题目四:
二分法排序:O(log N) 先是有序的数组。每次砍一半。
1)在一个有序的数组中,找某个数是否存在。
2)在一个有序数组中,找>=某个数最左侧的位置
3)局部最小值问题,定义:
1)[0]<[1] 0是局部小
2) [n-1]<[n-2] n-1是局部小
3) [i-1]<[i]<[i+1] i是局部小

问题五:
异或运算的性质与扩展
二进制操作
1)
异或运算 ,不同为一相同位零。(无进位相加)
同或运算 相同为一不同为零

2)
满足交换律和结合律
(无进位相加)
3)不用额外变量交换两个数(不用申请临时变量)

例题:假设一个数组[1,2,3,4,1,1,1,3,2,3,2,1,3,4]中只有一种数 出现奇数次
剩下的所有数 出现偶数次
怎么找到者种数

public static void printOddTimesNum1(int[] arr){
int eor = 0;
for(int cur : ar){
eor ^=cur;
}
System.out.println(eor);//是奇数eor必定不是0
}

假设一个数组[,2,3,4,1,1,1,3,2,3,2,1,3,4]中只有两种数 出现奇数次
剩下的所有数 出现偶数次
怎么找到者两种数

// arr种一定有两种数出现了奇数次,其他都出现了偶数次
public static void printOddTimesNum2(int[] arr){
int eor = 0;
for(int i = 0;i<arr.length;i++){
eor ^=arr[i];
}

//eor = a^b;
//eor !=0;
//eor必然是一个位置上是1
int righttOne = eor & (~eor +1);//二进制种  提取出最右的一个1
int onlyOne = 0;	//  eor'
for(int curr :arr){
   if((cur & rightOne) !=0){
		onlyOne ^= cur;
	}
}
System.out.println(onlyOne +"  "+(eor ^ onlyOne));

}

题目六:
ACM比赛
对数器:写的绝对正确的方法(用处:确定方法是对的)。

题目七:
剖析递归行为和递归行为的时间复杂度的估算
// 考虑溢出,mid=l+(r-l)/2;
// >>右移,相当于除二,还比较安全。 不会溢出

master公式:T(N)= aT(N/b)+O(N^d)
1)logb^a <d =>O(N^d); 大量的浪费比较次数
2) logb^a >d =>O(Nlogba);
3) logb^a == d =>O(logN * N^d); 比较行为没有浪费
规模相同
递归模型,子过程缩小的规模都是n/b,调用a次。剩下的时间复杂度都是N^d次方

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!