左神算法笔记01

时间复杂度

简单定义

简单理解为: 将一个算法的所有操作拆成基本操作(常数时间完成的操作)后,计算出操作次数和操作时间(可视为1)的乘积,即操作次数之和。在考虑最差情况时用O( )来表示时间复杂度,取最高项来表示。如O(N),O(logN)。

冒泡排序的例子

对N个数进行排列,则最差要进行1+2+3+……+N-1次交换操作和1+2+3+……N-1+N次查看操作,累加即为 N 2 2 + N 2 \frac {N^2} 2 + \frac N 2 2N2+2N,故时间复杂度为O( N 2 N^2 N2)

对数器

一种算法的纠错工具
用其它的保证正确的算法做同一道题,可以不在意效率(如穷举)。用随机数生成大量数据,两个算法一起跑,有差别就用出现差别的数据进行人肉排查,当次数足够多且无差异时,可以认为自己写的算法正确。

异或工具

定义

二进制中,两个数相同的位同为1或同为0时,将该位置为1,否则为0。
可用无进位的加法来理解。符号为:^
异或操作满足交换律和结合律,任意数 ^ 0= 本身

交换两个数的方法

public void swap(array[],i,j)//i和j不等,若相等会报错
{
	array[i] = array[i] ^ array[j];
	array[j] = array[i] ^ array[j];
	array[i] = array[i] ^ array[j];
}

简化一下,array[i]为a,array[j]为b
第一行执行后结果:

a = a ^ b
b = b

第二行执行后结果:

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

第三行执行后结果:

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

交换完成

有一组数,只有一个数出现奇数次,其它数出现偶数次,找到这个数

int eor = 0;
for(int i : array)//array为数组
	eor ^= i;

出现偶数次的数会两两抵消成为0,剩下的数异或0结果为其本身,即为出现次数为奇数的数。

有一组数,有两个不相同的数出现奇数次,其它数出现偶数次,找到这两个数

首先我们要知道怎么找一个二进制数最右边的1的位置

public int getdiff(int N)//N为待找的数
	int index;//为N最右边的1的位产生的数
	index = N ^ ((~N) + 1);
	return index;
/**
*例:
*N 			: 00101001000
*~N			: 11010110111
*~N+1		: 11010111000
*N ^((~N)+1): 00000001000
*/

我们对数组做一遍同样的操作,

int eor = 0;
for(int i : array)//array为数组
	eor ^= i;

此时,我们得到了eor = a ^ b,假设a,b分别为要找的两个数,那么他们异或的结果起码有一位为1,我们找到最右边为1的位

int index = getdiff(eor);
int a,b;
for(int i : array)
{
	if(i & index == 0) a ^= i;
	else b ^= i;
}

再将数组分为两块,进行异或操作结束就得到结果。

一些其它的位运算符的操作

a = a << 1;//a*2
a = (a << 1) | 1;//a*2+1
mid = left + (right - left) >> 1;//获取左右的中点
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值