算法(1)二分查找
2016-09-09 13:19
561 查看
基本概念
二分查找分类
1 综述
2 查询是否存在target返回值为boolean
3 查询target第一次出现的下标不存在则返回-1
4 查询target最后一次出现的下标不存在则返回-1
5 查询小于target中最大数的下标不存在则返回-1
6 查询大于target中最小数的下标不存在则返回-1
其他问题
缺点:查找的必须为有序表
要求:必须使用顺序存储,关键字必须有序排列
时间复杂度:O(logn)
代码中的查找队列均为int[],关键字以升序排列
二分查找分类
1 综述
2 查询是否存在target返回值为boolean
3 查询target第一次出现的下标不存在则返回-1
4 查询target最后一次出现的下标不存在则返回-1
5 查询小于target中最大数的下标不存在则返回-1
6 查询大于target中最小数的下标不存在则返回-1
其他问题
1. 基本概念
优点:比较次数少,查找速度快缺点:查找的必须为有序表
要求:必须使用顺序存储,关键字必须有序排列
时间复杂度:O(logn)
2. 二分查找分类
2.1 综述
假定要查找的关键字为target代码中的查找队列均为int[],关键字以升序排列
2.2 查询是否存在target,返回值为boolean
//普通的二分查找:从一个数组中查找某个数是否存在,如果存在则返回true,不存在则返回false public boolean targetExists(int[] nums, int target) { if( nums == null || nums.length == 0 ) return false; int l = 0, r = nums.length -1; while( l <= r ) {//是否有等号的关键在于,(l、r)与mid之间的关系 int mid = l+((r-l)>>1);//使用传统的(l+r)>>1,可能会溢出。同时+的优先级高于>> if( nums[mid] == target ) return true; if( nums[mid] > target ) r = mid-1; else l = mid+1; } return false; }
2.3 查询target第一次出现的下标,不存在则返回-1
//target第一次出现的下标,不存在则返回-1 public int firstTarget(int[] nums, int target) { if( nums == null || nums.length == 0 ) return -1; int l = 0, r = nums.length - 1; while( l < r ) { int mid = l+((r-l)>>1); if( nums[mid] == target ) r = mid;//由于这一步的存在,while条件不能是l<=r,否则可能会死循环 else if( nums[mid] > target ) r = mid-1; else l = mid+1; } //对于l是否会越界的思考 //如果l要越界,只有l=mid+1这一步才有这个可能性。 //有两个条件: //1. while(l<r)表示,当前数组长度肯定至少为2 //2. mid = l+((r-l)>>1)表示,当数组长度为偶数时,选择的是较小的中位数。如0,1,2,3,计算mid选择的是1而不是2 //这两个条件下,mid+1肯定不会越界 //相反,r可能会越界 if( nums[l] == target) return l; return -1; }
2.4 查询target最后一次出现的下标,不存在则返回-1
//target最后一次出现的下标,不存在则返回-1 public int lastTarget(int[] nums, int target) { if( nums == null || nums.length == 0 ) return -1; int l = 0, r = nums.length - 1; while( l < r ) { int mid = l + ((r-l+1)>>1);//可能会溢出,偶数个数时,选择第二个中位数 if( nums[mid] == target ) l = mid;//要选择靠后中位数的原因就在于l=mid。如果选择的是前一个中位数,当[2,3],target=2时,会造成死循环 else if( nums[mid] > target ) r = mid-1; else l = mid+1; } if( nums[r] == target ) return r; return -1; }
2.5 查询小于target中最大数的下标,不存在则返回-1
public int lastLessThanTarget(int[] nums, int target) { if( nums == null || nums.length == 0 ) return -1; int l = 0, r = nums.length - 1; while( l < r ) { int mid = l + ((r-l+1)>>1);//可能会溢出 if( nums[mid] == target ) r = mid-1; else if( target > nums[mid] ) r = mid-1; else l = mid; } //l和r都一样,因为最终都有l==r if( nums[l] < target ) return l; return -1; }
2.6 查询大于target中最小数的下标,不存在则返回-1
//返回第一个大于target数的下标 public int firstGreaterThanTarget(int[] nums, int target) { if( nums == null || nums.length == 0 ) return -1; int l = 0, r = nums.length - 1; while( l < r ) { int mid = l + ((r-l)>>1); if( nums[mid] == target ) l = mid+1; else if( nums[mid] > target ) r = mid; else l = mid+1; } //选择l或者r都一样,因为最终肯定有l==r if( nums[l] > target ) return l; return -1; }
3. 其他问题
给定数组长度(假设为n),问最多比较次数:二分查找的判定树是满二叉树,最多比较次数起始就是问节点数为n的完全二叉树的高度,即[log2n]取下整+1相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- C++二分查找在搜索引擎多文档求交的应用分析
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法