一:本周学习内容
- 实现管理系统
- 可变参数
- 不可变集合
- 算法练习
二:部分内容分享
时间复杂度:
是估计常数操作的一个指标
写出常数表达式数量,不要低阶项,且忽略掉高阶项的系数,剩下的部分如果为f(n),那么时间复杂度为O(f(n)),按最差的情况来估计
举例:
**选择排序,冒泡排序:**O(n^2),它们的时间复杂度不会受到数据的影响
**插入排序:**O(n^2),这是插入排序最差的情况,它的时间复杂度是会随着数据的改变而改变的
**二分查找:**O(logn) (算法中默认以二为底)
评价一个算法流程的好坏,先看时间复杂度的指标,如果指标无法判断,那么就用具体的操作去判断
常数操作
一个操作如果和样本的的数据量无关,每次都是固定时间内完成的操作,叫常数操作(如链表查找,就与样本的数据量有关,而在数组中查找,可以直接根据索引获取,无论获取哪个元素都是在固定的时间内完成的操作,与样本的数据量无关)
异或
特点:
1.N^N=0 N^0=N
2.异或满足交换律 结合律
3.用异或来实现交换
前提是a和b指向的不是内存中的同一块空间,值可以一样
不推荐使用
a=a^b;
b=a^b;
a=a^b;
异或相关算法题
- 在一个数组中,有一个数出现了奇数次,其余数均出现了偶数次求这个数
解法:将这个数组内元素不断异或,最后的值即为这个数
public class XORDemo01 {
public static void main(String[] args) {
int[]arr={1,22,22,34,34,55,55,55,55,2,2};
int eor=0;
for (int cur:arr){
eor^=cur;
}
System.out.println(eor);
}
}
- 在一个数组中,有两个不同的数出现了奇数次,其余数均出现了偶数次,求这两个数
若提取一个数源码中最右边的1,使其其余bit位上的数均为0,可以用这个数的源码与上补码 即 eor&(~eor+1)
public class XORDemo02 {
public static void main(String[] args) {
int []arr={23,23,1,1,45,67,67,70,70,70};
int eor=0;
int onlyOne=0;
for (int curNum:arr){
eor^=curNum;
}
//此时 eor=a^b;
//eor不为零,必然有个位置上是1
//获取最右边的1
int rightOne=eor&(~eor+1);
for (int cur:arr){
if ((cur&rightOne)==0){
onlyOne^=cur;
}
}
System.out.println(onlyOne+" "+(eor^onlyOne));
}
}