左神算法_第一节笔记

1 评估算法优劣的核心指标是什么

时间复杂度(流程决定)
额外空间复杂度(流程决定)(实现算法所需的额外空间,传入和返回的空间不算)
常数项时间(实现细节决定)(比拼常数项时间可以通过直接运行,看运行时间来比较)

2 常数时间的操作

如果一个操作的执行时间不以具体样本量为转义,每次执行时间都是固定时间。称这样的操作为常数时间的操作。

3 常见常数时间的操作

常见的算术运算、位运算、赋值、比较、自增自减操作等、数组寻址操作。
tips:
>> 带符号右移,右移后的符号位用原来的符号位填充
>>> 不带符号右移,右移后的符号位用 0 填充

4 选择排序

假设数组长度为n,则第一次遍历数组中下标为 0~ n-1的元素,找出其中的最小值,将其与下标为0的元素交换,第二次遍历数组中下标为 1~n-1 的元素,找出其中的最小值,将其与下标为1的元素交换,以此类推,每次都找出最小的并放在前面,直到数组排序完成。

5 冒泡排序

将数组相邻的两个数比较,较大的放在后方,第一轮遍历结束以后,数组中最大的值在数组的最后,第二轮遍历结束以后数组中第二大的值在数组的倒数第二位,以此类推直到数组排序完成。

选择排序先排最小的,冒泡排序先排最大的。

等差数列为 O(n^2)

5 插入排序

插入排序是先让数组的某个区间变得有序,然后逐渐扩大这个区间,当区间扩大到和数组一样大的时候,整个数组就有序了。
第一次看下标 0到0 区间是否有序,0到0只有一个数,必定有序,第二次看下标 0到1区间是否有序,如果下标1的数比下标0的数要小,则交换它们,交换后左边没有数了,0到1 区间有序了,第三次看下标 0到2 区间是否有序,如果下标2的数比下标1的数要大,因为左边已经是有序的了,所以可以得出下标 0到2 的区间已经有序了,如果下标2的数比下标1的要小,则将它们交换,交换后再与下标0的数比较,小了就换,大了就已经有序了。以此类推直到完成排序。

6 对数器

目标方法A和能正确完成功能的方法B,实现一个随机样本产生器,让方法A和方法B跑同样的样本对比结果,当某一样本结果不一致的时候,调试并改正方法,当样本数量很多而结果仍然一致时,可以确定方法A正确了。

7 二分

以在有序数组查找某一个数为例,每次都找当前区间的中点与之比较,如果目标比中点大,因为左边的数比中点要小,所以目标只可能出现在当前中点的右边,如果目标比中点小,因为右边的数比中点要大,所以目标只可能出现在当前中点的左边。这样逐步缩小区间直到找到目标或者没找到目标。

假设找到的次数为x,每次二分区间大小会变成上一次的 1/2,所以第x次的区间大小为 N*((1/2)^x),最差的情况时区间大小缩小至1才中止算法,此时 N*((1/2)^x)=1,化简得N=2^x,解得x=logN(以2为底),所以二分法的时间复杂度为 O(logN)(以2为底)。

能正确构建的左右两侧淘汰逻辑就可以二分。

8 异或运算

异或运算记成无进位相加:将数分解成二进制,逐位相加。但是 1+1也不进位。

异或性质:
1.0^N=N N^N=0
2.异或满足交换律和结合律(异或与计算顺序无关)

9 异或运算的运用

Q1:不使用额外变量交换两个数
A:

a=a^b
b=a^b
a=a^b

解析: 
a=a^b
b=a^b = a^b^b = a
a=a^b = a^b^a = b
注:仅当a与b不是同一对象时适用。

Q2:一个数组中有一种数出现了奇数次,其它数都出现了偶数次,找到并打印这种数
A:

public static void printOddTimesNum(int arr[]){
	int eor=0;
	for(int i=0;i<arr.length;i++){
		eor=eor^arr[i]
	}
	System.out.println(eor);
}

Q3:找出int型数二进制表示的最右侧的1,
A: N&(~N+1)

Q4:一个数组中有两种数出现了奇数次,其它数都出现了偶数次,找到并打印这种数
A:

public static void printOddTimesNum(int arr[]){
	int eor=0;
	for(int i=0;i<arr.length;i++){
		eor=eor^arr[i]
	}
	int rightOne=eor&(~N+1);//找到右边的第一个1
	int newEor=0;
	for(int i=0;i<arr.length;i++){
		if((arr[i] & rightOne) == 0){
			//找到rightOne右边第一个1位置上 不为1的arr,对他们异或,得出其中一个奇数
			newEor=newEor^arr[i];
		}
	}
	System.out.println(newEor +"   " +eor^newEor);
}

Q5:找出数字中的1
A:

public static int bit1Count(int N){
	int count=0;
	while(N!=0){
		rigthOne= N & (~N+1);
		count++;
		N=N^rightOne;
	}
	return count;
}

参考链接

1.左神算法
2.二分法logn时间复杂度解释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值