认识复杂度、对数器、二分法与异或运算
评估算法优劣的核心指标:
1.时间复杂度:
何为常数时间的操作:如果一个操作的执行时间不以具体样本
2.额外空间复杂度:
3.算法常数项时间:
认识对数器:
JAVA随机数组产生器:Math.random() --> [0,1)
Math.random()*N -->[0,N)
(int)Math.random()*N -->[0,N-1]
认识二分法:
时间复杂度O(log2N)
N2 等价于 N<<1 (左移)
N/2 等价于 N>>1 (右移)
N2+1 等价于 (N<<1)|1 (左移且与1或)
异或∧:N∧0=N; N∧N=0 异或可以理解为二进制无进位相加。异或满足交换律、结合律,就是说交换、结合不影响异或结果,无关
题目一:
不申请额外空间就可交换两个数(前提这两个指的不是同一个东西,要有两个空间互相倒,值一样无所谓):
如:int a = 1,int b= 2
交换: a = a ∧ b;
b = a ∧ b; (a∧b∧b=a)
a = a ∧ b;
题目二:
一个数组[a,b,c,d,e…]中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
让eor和所有的数都异或一次,最后返回的就是那个出现了奇数次的数
int eor = 0;
for(int i = 0;i<arr,length;i++){
eor = eor∧arr[i]
}
System.out.println(eor);
题目三
怎么把一个数提取出来最右侧的1
如:0000…11010100000 —?---> ans = 0000…00000100000
N&((~N)+1) 取反加1作与
题目四
一个数组中有两种书出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数
int eor = 0;
for(int i = 0;i<arr,length;i++){
eor = eor∧arr[i]
}
int rightOne = eor&((~eor)+1);
int onlyOne =0;
for(int i = 0;i<arr,length;i++){
if ((arr[i]&rightOne)!=0){
onlyOne ∧=arr[i];
}
}
System.out.println(onlyOne+" "+(eor∧onlyOne));
题目五
确定一个数二进制1有多少个
int count = 0;
while(N!=0){
int rightone = N&((~N)+1);
count++;
N ∧=rightone;
}
return count;
链表结构、栈、队列、递归行为、哈希表、有序表
单链表结构:
双链表结构:
JAVA会产生内存泄露原因:变量生存周期不一样
JVM释放的是通过任何途径都找不到的那个
栈:类似弹夹,数据先进后出
队列:好似排队,数据先进先出
栈和队列的实现:
双向链表实现,时间复杂度O(1)
数组实现(经典例题)
递归:
利用系统栈,帮你做了些事
任何递归行为都可以改成非递归,迭代(用循环)
递归符合T(N)=aT(N/b)+O(N^d)确定复杂度:
(数据量是N,所有子问题变成N/b的规模,a为函数里调用了几次递归,除去子问题之外的时间复杂度为O(N^d))
哈希表:
有序表:
可以向哈希表一样支持增删改查,但是可以乱序写入但是内部自动帮你排序。时间复杂度是O(logN)