二分查找
* 使用场景:数组内容有序
基础二分查找法
int i = 0;int j = a.length-1;
//此处如果不是等于,则会少计算一步,导致部分判断失效
while(i <= j){
int m = (i+j)>>>1;
if(target < a[m]){
j = m-1;
}else if(target > a[m]){
i = m+1;
}else{
return m;
};
#### 运算符
右移运算符 >>1 相当于除以2 向下取整 二进制表示 如果为正数,则前面补0负数补1
左移运算符 <<1 相当于乘以2
无符号右移动运算符 >>>1 相当于除以2,取绝对值 向下取整 二进制表示 前面补0
#### 二分查找法-改
i
int i = 0;int j = a.length;
while(i < j){
int m = (i+j)>>>1;
if(target < a[m]){
j = m;
}else if(target > a[m]){
i = m+1;
}else{
return m;
};
#### 二分查找法--平衡版
int i = 0;int j = a.length;
while((j-i) > 1){
int m = (i+j)>>>1;
if(target < a[m]){
j = m;
}else{
i = m;
}
}
if(a[i] == target){
return i;
}else{
return -1;
}
#### 二分查找法--重复数据--最左or最右
int i = 0;
int j = a.length-1;
int candidate = -1;
while(i <= j){
int m = (i+j)>>>1;
if(target < a[m]){
j = m-1;
}else if(target > a[m]){
i = m+1;
}else{
candidate = m;
//最左
j = m-1;
//最右
i = m+1;
}
}
return candidate;
#### 二分查找法--重复数据--最左or最右--改
//最左
while(i <= j){
int m = (i+j)>>>1;
if(target <= a[m]){
j = m-1;
}else{
i = m+1;
}
}
return i;
//最右
while(i <= j){
int m = (i+j)>>>1;
if(target >= a[m]){
i = m+1;
}else{
j = m-1;
}
}
return j;
#### 大O表示法--时间复杂度
* 单项式中 常量可以忽略
* 多项式中,低次项可以忽略
可表达为 O(g(n))
按时间复杂度从低到高
黑色横线 O(1),常量时间,意味着算法时间并不随数据规模而变化
绿色 O($log(n)$),对数时间
蓝色 O(n),线性时间,算法时间与数据规模成正比。
橙色 O($n * log(n)$),拟线性时间
·红色 O($n^2$)平方时间 工
黑色朝上 O($2^n$)指数时间
O(n!)
1. 渐进上界 最差情况 O
2. 渐进下界 最优情况 Ω
3. 渐进紧界 技能作为上届,也能作为下届 Θ