常见算法基础题思路简析(四)-二分搜索篇
2017-09-28 22:09
344 查看
常见算法基础题思路简析(四)-二分搜索篇
标签: algorithms常见算法基础题思路简析四-二分搜索篇
求完全二叉树的节点个数
最左原位
元素最左出现
局部最小值位置
循环有序数组最小值
快速N次方
本文对和 二分搜素 有关的常见算法基础题思路分类进行分析和总结,并以 Java 为例,适当指出需要注意的编程细节
相关题目和代码在 GitHub: https://github.com/brianway/algorithms-learning
题目见
com.brianway.learning.algorithms.lectures.binarysearch包
求完全二叉树的节点个数
题目见CountNodes
思路:
计算根节点到最左节点的高度 h
同理,计算根节点到其右孩子的最左节点的高度 hr
如果 h > hr,则节点个数为:根节点右子树的节点数+1(根节点)+根节点左子树的节点数
如果 h <= hr,则节点个数为 根节点左子树的节点数+1(根节点)+根节点右子树的节点数
注意:
计算 hr 时,
current = root.right, 初始值为 1(代表根节点)
h > hr,说明右子树为满二叉树,高度为 h-2,
根节点右子树的节点数+1可直接计算,为
2^(h-2)
同理,h <= hr,说明左子树为满二叉树,高度为 h-1
最左原位
题目见Find
思路:类似二分搜索,当
a[i]=i时终止,有序数组且元素各不相等,所有 a[i] 每次的增量是要大于下标 i 每次的增量 1 的。
判断边界条件
lo = 0, hi = n-1,开始二分搜索
若
a[i] > i,则 任意 j > i,有
a[j] > j,所以只可能出现在左半部分,故 hi = mid - 1
若
a[i] < i,则 任意 j < i,有
a[j] < j,所以只可能出现在右半部分,故 lo = mid + 1
注意:
边界条件:
arr[0] > n - 1 || arr[n - 1] < 0时无解,直接返回
最后求得
arr[mid] = mid->
res = arr[mid]后,记得赋值
hi = mid - 1,且不能跳出循环,因为要找 最左原位,所以需要继续循环下去。
元素最左出现
题目见LeftMostAppearance
思路:这里就是一个简单的二分查找,唯一不同的是,当
arr[mid] = num时,不是在
res = mid后直接退出循环,而是需要赋值
hi = mid - 1继续循环
局部最小值位置
题目见LocalMin
思路:
判断两端边界情况,满足条件(
arr[0]<arr[1]或者
arr[n-2]>arr[n-1])则直接返回结果
判断
arr[mid]和
arr[mid - 1]的大小,若
arr[mid]大,则一定有个局部最小出现在左边
否则,判断
arr[mid]和
arr[mid + 1]的大小,若
arr[mid]大,则一定有个局部最小出现在右边
若都不满足,则局部最小为
arr[mid]
注意:
注意数组为空,长度为 1,以及其他边界情况
思路中 2,3 步的依据就是,先有 1 中段边界判断,所以一定有两端元素大于其紧邻元素(
arr[0]>arr[1]且
arr[n-1]>arr[n-2])。数组要么一直递减到边界的紧邻元素从而结束循环,要么在这个过程中遇到某个局部最小,所以一定是有解的。
循环有序数组最小值
题目见MinValue
思路:循环有序数组截出一个连续的子数组还是循环有序的。在每次循环中进行一下判断:
若
arr[lo] < arr[hi],说明子数组已经升序,直接返回
arr[lo]。 否则,说明数组不升序,进行下面的步骤
若
arr[lo] > arr[mid],最小值出现在左半部分
若
arr[lo] < arr[mid],最小值出现在右半部分(因为说明
arr[lo] ~ arr[mid]是升序的)
若
arr[lo] = arr[mid],最小值为第一个小于
arr[lo]或者就是
arr[lo]本身
注意:
注意可能有重复元素的问题,所以在遇到
arr[lo] = arr[mid]时,需要遍历
lo ~ hi之间的元素来找到最小值
这里的左右指针更新需要注意,
hi = mid和
lo = mid,而不是
mid-1和
mid+1,因为不能漏掉元素
快速N次方
题目见QuickPower
思路:求出 k 的 1,2,4,8….次方作为中间值 tmp,减少相乘的次数
每次把 N 右移一位,若该位为 1,则将结果乘以中间值 tmp
每次令中间值 tmp 等于自己的平方(对应于第一步中的位移操作)
注意:
注意越界问题,按题目要求,求 mod 某个数后的结果
作者@brianway更多文章:个人网站
|CSDN
|oschina
相关文章推荐
- 常见算法基础题思路简析(四)-二分搜索篇
- 常见算法基础题思路简析(二)-链表篇
- 常见算法基础题思路简析(三)-二叉树篇
- 常见算法基础题思路简析(三)-二叉树篇
- 常见算法基础题思路简析(五)-队列和栈篇
- 常见算法基础题思路简析(五)-队列和栈篇
- 常见算法基础题思路简析(六)-字符串篇
- 常见算法基础题思路简析(六)-字符串篇
- 常见算法基础题思路简析(一)-排序篇
- 常见算法基础题思路简析(一)-排序篇
- 常见算法基础题思路简析(一)-排序篇
- 常见算法基础题思路简析(二)-链表篇
- 【常用算法思路分析系列】与二分搜索相关高频题
- 【基础算法】搜索-二分搜索
- 算法与数据结构-二分搜索 讲解与java代码实现
- 算法——二分搜索
- 数据结构与算法(4)----->链表、二分搜索
- PHP:冒泡排序、快速查找和二分查找的思路以及算法
- 基础算法学习(01)-二分查找
- 算法与数据结构基础系列(一): 链表的常见问题分析及实现