二分法
二分法体现了一种“分治”的思想。
二分查找
当需要在一个数组中查找某个元素的时候,我们自然而然地想到遍历整个数组,找到想要的元素就停止查找。这种方法的时间复杂度是O(n),那么有没有一种更高效一点的方法呢?这时候就轮到二分查找登场了,二分查找的时间复杂度是O(logn),显然是更高效的做法。不过使用二分查找需要有一个前提:数组必须是有序的。因为二分查找是通过比较来进行提速的,如果数组是乱序,或者元素无法进行比较,显然二分查找也就失效了。
1 | int find(vector<int>& nums, int begin, int end, int target) |
上面代码是一种二分查找的递归实现,begin
表示要查找的开始位置,end
表示要查找的最后位置,如果begin
大于end
,显然整个元素就不在数组中,返回-1表示没有找到。
计算中间位置,如果中间位置的元素正好等于要查找的元素,就返回这个位置,否则的话,比较一下目标元素是比中间位置的元素大了还是小了,小了的话,说明在前半段中,否则相反。
总结:对于有序数组来说,二分查找是一种比较好的算法。
二分插入
leetcode上有一道简单难度的题,找到目标值,返回索引,如果不存在,则返回插入位置,要求时间复杂度在O(logn)。很明显是让使用二分法来做。
1 | int insert(vector<int>& nums, int begin, int end, int target) |
只需要把找不到的情况返回值从-1改成当前的下标即可。(end取闭区间还是开区间只会影响找不到时的判断条件,闭区间的话就是begin > end
,开区间的话就是begin == end
,STL中的做法都是取开区间,所以推荐和标准库保持一致,这样哪怕以后和库有交互也不至于头疼)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 cwt技树年轮!
评论