数据结构算法学习记录1--参考素材b站2021最新左神数据结构算法全家桶

算法,画龙点睛之笔也

一.评估算法优劣的核心指标是什么?

1.时间复杂度(流程决定)
2.额外空间复杂度(流程决定)
3.常数项时间(实现细节决定)
常数时间的操作:执行时间固定,与样本量无关
例:
常数的算数运算(+,-,*,/,%)
常见的位运算(>>,>>>,<<,|,&,^)
赋值,比较,自增,自减
数组寻址操作

二.认识时间复杂度

1.时间复杂度

(1)时间复杂度为一个算法流程中,常数操作数量的一个指标,常用O(读作big O)来表示。

(2)先熟悉这个算法流程,然后统计这个算法流程中进行了多少次常数操作,进而写出表达式。

(3)在该表达式中,只要高阶项,不要低阶项,也不要高阶项的系数,剩下的部分如为f(N),那么时间复杂度为O(f(N))
(4)评价一个算法流程的好坏,先看时间复杂度,再分析不同数据样本下的实际运行时间,这个时间就叫“常数项时间”

2.异或运算

性质
性质10^ N= N ;N^ N=0;
性质2a^ b = b^ a;(a^ b)^ c=(a^ b)^c;
性质3同一组数异或,结果不受先后影响

*知识点
不需要其他变量参与的swap()写法:
*注意:这种方式操作的前提要保证a和b在为内存中两个独立的区域

int a=甲;
int b=乙;
a=a^b;    //a=甲^乙           b=乙
b=a^b;    //a=甲^乙           b=乙^甲^乙=0^甲=甲
a=a^b;    //a=甲^乙^甲=0^乙=乙 b=甲

*面试题
给出一个数组,该数组全部为int型数据,
( 时间复杂度为O(N),空间复杂度为O(1) )
(1)数组中有一种数为奇数次,其他数为偶数次
思路:把所有数异或
(2)数组中有两种数为奇数次,其他数为偶数次
思路:
在整型数的32位中,他们必然有1位不一样,而这位就是它们异或
后结果为1的那位,我们通过这一位将整个数组分成两份,使其中一份
异或就可以得到,两个数其中一个数。再异或它俩的异或结果就可以得
到另一个数

public static void q1(int[] arr){

	int eor=0;
	
	for(int cur:arr){
		eor^=cur;
		//eor与数组中全部的数异或,最后得到的是那一种数
	}
	
	System.out.println(eor);
}


public static void q2(int[] arr){
	int eor=0;
	
	for(int curNUM:arr){
		eor^=curNUM;
	}
	//eor=a^b
	//eor!=0
	//eor必有一个位置上是1
 	int rightone=eor&(~eor+1);//提取出一个数最右侧的1 (1*)

	int onlyone=0;
	for(int cur:arr){
		if((cur&rightone)==0){
		//把数组中的所有数与rightone相乘等于0的数才把它与onlyone异或
		这样就可以数分成两组,而我们要求的两个数必然不在一组,因为
		在整型数的32位中,他们必然有1位不一样,而这位就是它们异或
		后结果为1的那位,我们通过这一位将整个数组分成两份,使其中一份
		异或就可以得到,两个数其中一个数。再异或它俩的异或结果就可以得
		到另一个数
		onlyone^=cur;
		}
	}
	System.out.println(onlyone+" "+(eor^onlyone));
}

(1*)代码解释

int rightone=eor&(~eor+1);

/*如eor为1010111100
	   		 eor:  1010111100
	  		~eor:   0101000011
		  ~eor+1:   0101000100
	eor&(~eor+1):   0000000100
*/

3.时间复杂度是按最差情况下的时间来估计

举例:插入排序
解释:当数组的顺序为5,4,3,2,1时,此时插入排序每个数都要进行排序,则需第一个数排0次,第二个数排1次,第三个数排2次,第四个数排3次,第五个数排4次,这是等差数列。则时间复杂度为O(N^2),但当数组顺序为1,2,3,4,5时,此时每个数都不需要进行排序,则时间复杂度为O(N)
*知识点
时间复杂度的还有其他表现形式:
(1)平均时间复杂度的表现形式
(2)最好时间复杂度的表现形式
我们同常用的时间复杂度O()(最差时间复杂度的表现形式)

三. 对数器

解释:
方法a(理论方法) 随机样本产生器 方法b
随机样本产生器产生初始样本分别给方法a和方法b,让两个方法执行该样本

1.随机样本产生器

例子:数组的随机样本产生器

//Math.random->[0,1)所有的小数,等概率返回一个
//Math.random->[0,N)所有小数,等概率返回一个
//(int)(Math.random()*N)->[0,N-1]所有的整数,等概率返回一个
public static int[] RandomArray(int maxSize,int maxValue){
		int[] arr=new int[(int)((maxSize+1)*Math.random())];
		for(int i=0;i<arr.length;i++){
				arr[i]=(int)((maxValue+1)*Math.random())-(int)(maxValue*Math.random());
		}
		return arr;
}

2.对数器的详细讲解

public static void main(String[] args){
		int testTime=50000;//进行50000次对比
		int maxSize=100;
		int maxValue=100;
		boolean s=true;
		for(int i=0;i<testTime;i++){
				int[] arr1=RandomArray(maxSize,maxValue);
				int[] arr2=copyArray(arr1);
				insertSort(arr1);
				comparator(arr2);
				if(!isEqual(arr1,arr2)){
						s=false;
						break;
				}
		}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值