《二分查找:一个数组的“自我修养”》
目录
一、我和数组的“猜数字”游戏
1. 普通人的线性查找
2. 二分大佬的降维打击
二、那些年,我踩过的坑
1. 边界の迷惑行为
2. 重复元素の修罗场
三、花式玩法大赏
1. 旋转数组の杂技
2. 数学题的伪装者
四、灵魂拷问时间
—— 论如何在有序生活中优雅摆烂
一、我和数组的“猜数字”游戏
某天,我盯着电脑屏幕上的有序数组,它傲娇地喊:“你猜我在哪~”
1. 普通人的线性查找
我(卑微打工人版):
for(int i=0; i<arr.size(); i++){
if(arr[i]==target)
cout << "找到啦!在" << i << "号坑位";
}
// 内心OS:数组长了之后,这简直是《打工循环》真人版[2]()
2. 二分大佬的降维打击
数组突然掏出墨镜:“给你三次机会,猜中我请你喝奶茶!”
int left=0, right=arr.size()-1;
while(left <= right){
int mid = left + (right-left)/2; // 防溢出の优雅[1]()
if(arr[mid] == target)
return mid; // 奶茶到手!
else if(arr[mid] < target)
left = mid + 1; // 右半场继续卷
else
right = mid - 1; // 左半场躺平
}
// 只需log2(n)步,程序员发量+10%[4]()
二、那些年,我踩过的坑
1. 边界の迷惑行为
死循环の诅咒:
while(left < right){
// 如果这里写成了left=mid...
// 恭喜获得《无限月读》体验卡[1]()
}
生存法则:记住循环条件是left<=right
,调整边界要mid±1
2. 重复元素の修罗场
当数组里有3个相同的7:
// 查找第一个7时
if(arr[mid] >= target)
right = mid - 1; // 像极了恋爱中的试探[2]()
else
left = mid + 1;
// 最终left会停在第一个7的位置,深藏功与名
三、花式玩法大赏
1. 旋转数组の杂技
当数组被熊孩子旋转后(如[4,5,6,7,0,1,2]):
if(arr[mid] > arr[right])
left = mid + 1; // 右半区是乱序の宝藏地
else
right = mid; // 左半区岁月静好
// 像在玩《大家来找茬》[4]()
2. 数学题的伪装者
求平方根时:
while(right - left > 1e-6){
mid = (left + right)/2;
if(mid*mid > x)
right = mid; // 数值太大,缩!
else
left = mid; // 数值太小,冲!
}
// 原来二分查找也会《变形记》[1]()
四、灵魂拷问时间
Q:为什么要用二分查找?
A:因为生活已经够无序了,至少在代码里追求一下有序2
Q:学不会怎么办?
A:建议把本文代码打印出来贴在床头,梦里都是left
和right
在跳舞4
(插图脑补建议:程序员头顶稀疏的头发逐渐浓密,旁边配字“感谢二分法救我狗命”)