2016/3/25
二分查找,应该是面试里比较简单但是也会问道的问题。
这个代码,是我初看见二分查找的原理时写的,用的递归。好吧,有明显的错误,就是当寻找的值不在数组中时会越界。
int FindX(const vector<int>& a,int left,int right ,int k)
{
int center = (left + right) / 2;
if (k>a[center])
{
FindX(a, center+1, right, k);
}
else if (k<a[center])
{
FindX(a, left, center, k);
}
else if (k == a[center])
{
return a[center];
}
else
{
return -1;
}
}
举个例子,如果数组是(1,2,3,4),要查找5时,center就会一直往上加。
真正的二分查找。
int binarySearch(const vector<int> &a, const int k)//真正的二分查找
{
int low = 0, high = a.size() - 1;
while (low<=high)
{
int mid = (low + high) / 2;
if (a[mid]>k)
{
high = mid - 1;
}
else if (a[mid]<k)
{
low = mid + 1;
}
else
{
return a[mid];
}
}
return -1;
}
可以看出来是把边界往中间移,来堵死要查找的数,当边界重合但是还没有找到数的时候,就跳出循环,返回-1。
在学习数据结构与算法的时候,都会觉得自己是个智障,同时钦佩这些创造算法的人。
2016/6/26
今天突然想起来了,自己改了一下之前的递归形式。发现当时自己好弱,只要加个边界检测就好了,但是当时都不会写。
递归的会爆栈的原因,主要是如果k比现有的数大,左边界会一直增加,或者相反,右边界一直减小。
int FindX(const vector<int>& a,int left,int right ,int k)
{
if (right<0||left>(a.size()-1))
{
return-1;
}
int center = (left + right) / 2;
if (k>a[center])
{
FindX(a, center+1, right, k);
}
else if (k<a[center])
{
FindX(a, left, center-1, k);
}
else if (k == a[center])
{
return a[center];
}
else
{
return -1;
}
}
也工作了一段时间,真的要重视基础。任何时候,花费多少努力夯实基础都是有意义的。
分享一句之前微博上看见的话,觉得讲得不只是画画,任何学习都适用。
“画画要学透视,画场景要学材质,画原动画要学运动规律,画分镜要学视听语言,画前期还得学做中期…很烦对不对?无数人都想跳过这些基本功,直接按感觉来,结果达到一定程度后就n年再无进步。所以我常和新人说,所有这些你觉得烦的东西就好比铠甲,你身体强壮,铠甲就让你如虎添翼;你身体羸弱,铠甲本身就把你压垮了。你们看到的大师们基本都是开着高达来战的。”