二分法

二分法题型小结

不羁岁月 提交于 2019-12-02 11:26:29
在刷题的过程中,二分法用的还是挺多的,有时候超时了往往是你没有用上二分法,今天我就来稍微总结下用的最多的三种 二分法搜索 。 一、搜索和目标值相等的数 这一类是最简单的,例如对于数组 arr = {1, 2, 5, 6, 9},要我们搜索返回目标数 target = 6,这个时候我们需要返回 6 的下标 i = 3。代码如下 int binarySearch ( int [ ] arr , int target ) { int left = 0 , right = arr . length - 1 ; while ( left <= right ) { int mid = left + ( right - left ) / 2 ; if ( arr [ mid ] == target ) return mid ; else if ( arr [ mid ] < target ) left = mid + 1 ; else return mid ; } return - 1 ; } 不过这个有一个需要注意的点,就是很多人在求 mid 的时候,会这样写 mid = (left + right) / 2; 其实这样写是有点小问题的, 因为 left + right 有可能导致数值溢出 ,从而 mid 的计算就错误了,所以经常这样写的小伙伴要注意了,严谨的写法应该是这样写: mid =

在旋转数组中搜索 二分法

房东的猫 提交于 2019-12-02 11:08:13
class Solution : def search ( self , nums : List [ int ] , target : int ) - > int : left , right = 0 , len ( nums ) - 1 while ( left <= right ) : mid = ( left + right ) // 2 print ( nums [ mid ] ) #如果中间的数字比目标大 有两种可能 可能目标在左边或者在右边 如果目标大于right那么肯定在左边 用二分法就行 #如果目标小于right并且中间的数字也比right小 #如果目标小于right 那么肯定在右边 left至少是mid+1 if nums [ mid ] > target : if target > nums [ right ] : right = mid - 1 elif nums [ right ] > target : if nums [ mid ] < nums [ right ] : right = mid - 1 else : left = mid + 1 else : return right #如果中间的数字比目标小,那么目标可能在右边也可能在左边 #如果目标比right小 那么一定在右边 #如果目标比right大 那么一定在左边

二分法查找有序数组

限于喜欢 提交于 2019-12-02 11:01:01
二分法查找索引 package Array ; public class TestbinarySearch { public static void main ( String args [ ] ) { //给定一个有序数组 int Arr [ ] = { 3 , 12 , 15 , 45 , 68 , 78 , 98 } ; //指定查询的元素 int num = 12 ; //用二分法查找,返回索引 int start = 0 ; int end = Arr . length - 1 ; //end的设置应该为数组最后一位 int index = - 1 ; //用于标志是否查找到指定元素 while ( start <= end ) { int mid = ( start + end ) / 2 ; int midElem = Arr [ mid ] ; if ( num = midElem ) { index = mid ; break ; //第一次查找就找到了,即推出循环 } else if ( num > midElem ) { start = mid + 1 ; } else { end = mid - 1 ; } //判断指定元素在mid的什么位置,改变start和end的值 } } //输出结果 if ( index == - 1 ) { /

【C++】二分法搜索实现

无人久伴 提交于 2019-12-02 05:44:42
/*--> */ /*--> */ 二分法搜索实现 C++ 主要思路:   在[有序]序列中寻找某个给定值得位置,从中间位置开始搜索,如果中间位置正好是给定值,搜索完成;   如果不是,若中间位置的值大于给定值,则在前半段序列进行搜索;   若中间位置的值小于给定值,则在后半段序列进行搜索。   伪代码: 1 // 中间位置计算方法 若text长度为偶数,length/2 + begin 为中间两位的右侧; // 若text长度为奇数,length/2 + begin 为正中央位置。 2 3 // 注意: text.end 是尾元素的下一个位置 称为 [尾后迭代器] 4 5 mid = text.begin + text.length/2; 6 7 // 按照算法思路进行搜索 8 9 while(text.mid!=text.end&&!*text.mid!=value){ 10 11 if(value < text.mid) 12 13 end = mid; 14 15 else 16 17 begin = mid + 1; 18 19 // 重新确定中间位置 20 21 mid = text.begin + text.length/2; 22 23 } 24 25 C++ 示例: 1 #include <iostream> 2 #include <string> 3 using

[总结]二分法(二分查找)

青春壹個敷衍的年華 提交于 2019-12-02 03:54:37
[总结]二分法(二分查找) 一、关于二分法 二分法是一种很平常却又很重要的算法。二分法能为我们解题时提供很大的帮助。 1. 使用前提 二分法的适用条件是序列具有 二分性 ,也就是单调性。当序列具有二分性,这时我们不断枚举区间中点才能判断这个值是否题设条件。 当题目中出现诸如 最大值的最小 , 最小值的最大 的问题时,答案具有二分性。 2. 分类 从二分的对象来分类,我们既可以二分最终的答案,我们也可以二分进行判断。 从二分的类型来分类,可以分为 整数域上的二分 ,以及 实数域上的二分 。 3. 易错点 二分法简单易写,但是却很容易写错。我们有很多方法实现二分,而其中的细节地方需要仔细考虑。 对于整数域上的二分: 我们需要注意终止条件,左右区间位置的变化,避免错过答案或造成死循环。 对于实数域上的二分: 我们需要注意精度的控制。 建议自己形成固定的代码模型,避免造成不必要的错误。 4. 二分法的延伸 C++ STL中的 lower_bound , upper_bound 也可以解决实现在一个序列中二分查找某个整数 k 的后继。 二分法能够解决单调问题,进一步地,我们可以扩展二分法至 三分法 。此时三分法可以解决单峰函数的极值问题。 二、整数域上的二分 1. 模板 在这里给出一种常见的模板: while(l<=r){ int mid=(l+r)>>1; if(check(mid)){

算法学习:二分法

。_饼干妹妹 提交于 2019-12-01 10:23:36
说明: 函数binary_search接受一个有序数组和一个元素,如果指定的元素包含在数组中,这个函数将返回其位置。开始时查找整个数组,每次检查中间的元素,如果猜的数小了,对应修改low;如果猜的数大了,对应修改high。 代码: 1 def binary_search(list1,item): 2 low = 0 3 high = len(list1)-1 4 5 while low <= high: #只要范围没有缩小到只包含一个元素 6 mid = (low+high)//2 #检查中间元素 7 guess = list1[mid] 8 if guess == item: 9 return mid #返回索引 10 if guess > item: 11 high = mid -1 12 if guess < item: 13 low = mid + 1 14 15 return None 16 17 my_list = [1,3,5,7,9] 18 19 print(binary_search(my_list,7)) 20 print(binary_search(my_list,3)) 21 print(binary_search(my_list,-1)) 结果: 3 1 None 来源: https://www.cnblogs.com/hqq2019-10/p

对第二章分治法的总结

…衆ロ難τιáo~ 提交于 2019-11-30 19:58:04
分治法是将较大规模的问题划分为较小规模的问题提高解决问题的效率。 二分法是分治法的一个特殊方法,通常和递归算法结合使用。 个人认为这个算法提供给我们一个新的解决问题的思路。 使用二分法的关键在于找到分解为子问题的方式,分解方式不同也会影响算法的效率,比如说二分排序中有合并排序和快速排序两种。虽然这两种排序方法的时间复杂度都是nlog(n),但是对于不同的数据,两者排序的效率还是有一定差别的。对于基本排好序的数据集来说,快速排序会比较高效一些。 来源: https://www.cnblogs.com/coding-specification-of-Java/p/11638636.html

算法第二章上机实践报告

我的未来我决定 提交于 2019-11-30 06:30:39
总的来说,上机体验感还好,因为其中前两道不是我打的,但是思路是我想的,一部分是另外一个成员想的,我们很默契,想法一致,思路有时候可以一起说出来。 首先第一道题主要是二分法,但是中间有一个次数增加的那里,费了很多工夫,我们一开始把它放在了外面,所以就多增加了一次,后来问了一下老师就懂了。第一道题其实挺简单的。 第二道题是这样,前面都是一样的其实和第一道题没什么区别,思路我想了一部分,最后升华的部分是另一个队友想出来的,这一点确实是我没有想到的点,都是二分搜索,但是后面有一点不一样,要判断边界的,最后我们也通过了测试。 第三题是现在我自己在做的,但是复杂度是log(n),测试的时候最大值总是不对,出现段错误,现在还在改进中,算法应该用二分法,希望我今天可以写出来,嘻嘻。 希望下一次的上机体验感还是一如既往的好,哈哈哈哈哈哈哈 来源: https://www.cnblogs.com/XJWQ/p/11568690.html

控制二分法

家住魔仙堡 提交于 2019-11-30 06:15:54
儒家和佛学都强调无欲则刚,我一直不理解,没有欲望为什么就会变得刚强?一个人怎么会没有欲望呢?我们平时的贪欲、爱欲、甚至食欲这不都是欲望吗?怎么会消除呢?这太难做到了,直到我看到斯多葛学派的安心之法,才发现原来是我将无欲则刚给理解错了。 1、一段名言 中国科技大学的前校长朱清时用这样一段话来勉励学生: 有勇气去改变你能改变的事情; 有度量去接受你不能改变的事情; 有智慧区别以上两类事情; 上面这句话最起源于斯多葛学派,基督教和犹太教也有类似的名言,上面这段话看起来很普通,但实则这段话厉害非凡! 我们从上面一段话当中我们看出来,这段话把世界的事情分为了两类,一类是我们可以控制改变的,另一类是我们不可以控制改变的。如果你真能区别你能控制的事情和你不能控制的事情,并且将两者区别对待,那么在心理上就真的可能做到不可战胜。 2、一个心法 A早上上班的时候发现自己钱包不知道什么时候被偷了,早上的时候他记得明明放在身上的,钱包里面还有A的身份证、多张银行卡和一些现金。 假设A是一个普通人,那么他很可能一天都会情绪低沉,工作没有效率,生活没有激情。钱包里面东西对于A来说确实挺重要的,补办身份证和银行卡确实挺麻烦的;假设B接受了斯多葛学派的控制二分法,知道了钱包被偷是他不能控制的事情,沮丧和抱怨都没有任何的用处,只能坦然接受,然后抽空去补办相关证件。这一天刚刚开始,虽然B无法控制钱包被偷,但他知道

二分法查找法学习笔记总结

纵然是瞬间 提交于 2019-11-29 16:34:30
1 二分法学习笔记总结 参考 https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/ https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/ 1.1 取中位数索引的方法 传统的方法 int mid = (left + right) /2 ,在 left 和 right 比较大的时候, 两者相加很可能超过 int 类的最大值,即发现整型溢出; 改进 int mid = left + (right - left) /2 最好的写法 int mid = (left + right) >>> 1 >> , 右移时,丢弃右边指定位数,左边补上符号位; >>>, 无符号右移运算符 ,丢弃右边指定的位数,左边补上 0 。所以对负数右移,可以变成正数; 1.2 循环条件 while (left <= right) ,退出循环时,要考虑返回 left 和 right; 2