二分查找

二分查找(折半查找)

谁说我不能喝 提交于 2020-01-29 20:38:10
二分法检索(binary search)又称折半检索,二分法检索的基本思想是设数组中的元素从小到大有序地存放在数组(array)中,首先将给定值key与数组中间位置上元素的关键码(key)比较,如果相等,则检索成功; 否则,若key小,则在数组前半部分中继续进行二分法检索; 若key大,则在数组后半部分中继续进行二分法检索。 这样,经过一次比较就缩小一半的检索区间,如此进行下去,直到检索成功或检索失败。 二分法检索是一种效率较高的检索方法。 import java . util . Arrays ; public class TestBinarySearch { public static void main ( String [ ] args ) { int [ ] arrs = { 30 , 20 , 50 , 10 , 80 , 9 , 7 , 12 , 100 , 40 , 8 } ; Arrays . sort ( arrs ) ; System . out . println ( Arrays . toString ( arrs ) ) ; System . out . println ( binarySearch ( arrs , 30 ) ) ; } public static int binarySearch ( int [ ] array , int value

手撕二分查找及其变种,就是干!

元气小坏坏 提交于 2020-01-28 16:49:49
一、初探二分查找 在面试的时候,尤其的一面,感觉让你手写二分,还真的不一定就能很快写出来,所以在此总结分享给大家 1 二分查找是什么? ”查找“顾名思义是在一堆数去找出我们需要的数,但是我们又想更快的找出我们需要找的数,所以我们就尽量的减少查找比较的次数。"二分"就是分成两份来减少我们查找次数。 不急不急,假设我们这里有十个数,我们来画图看看这是个什么神操作。 从上图我们知道,我们每次都和区间的中间项值进行比较,从而缩小查找区间的值。 2 时间复杂度? 这里我们假设搜索区间一共n个数,第一次切分n/2,第二次n/4,第三次n/8..........n/2(k).这是一个等比数列,n/2(k)=1,k=log2n,那么时间复杂度为logn. 二 、二分的注意事项 1 二分查找要求数据必须是有序的。 2 二分查找依赖于数组随机查找的特性,要求内存连续 三 、二分的实现 1 第一种小白写法 int BinarySerach(vector<int>& nums, int target) { int left = 0, right = nums.size(); while (left < right) { int mid = (left+right)/2; if (nums[mid] == target) return mid; else if (nums[mid] < target)

pat甲级1044二分查找

北慕城南 提交于 2020-01-27 02:43:11
1044 Shopping in Mars(25 分) Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diamond has a value (in Mars dollars M$). When making the payment, the chain can be cut at any position for only once and some of the diamonds are taken off the chain one by one. Once a diamond is off the chain, it cannot be taken back. For example, if we have a chain of 8 diamonds with values M$3, 2, 1, 5, 4, 6, 8, 7, and we must pay M$15. We may have 3 options: Cut the chain between 4 and 6, and take off the diamonds from the position 1 to 5 (with values 3+2+1+5+4=15).

二维数组的查找(编程题目)

喜你入骨 提交于 2020-01-26 21:22:07
二维数组的查找 题目分析 暴力求解 O ( n l g n ) O(nlgn) O ( n l g n ) python代码如下: 技巧法 O ( n ) O(n) O ( n ) python代码如下 二维二分查找法 O ( l g n ) O(lgn) O ( l g n ) python代码如下 题目描述:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 题目分析   任何一道算法题,在拿到题目之后,都是首先从基础的题干入手,了不起我看不懂任何题干中的隐藏信息,我直接暴力求解,起码让自己有一定的思路,先能解决问题,对于笔试题目的编程,有可能由于测试用例的量级比较小,直接求解了。而且对于一般的问题(排除很明显的动态规划、或者贪心算法暗示,这种题目暴力法很可能达到指数复杂度)。最最最传统的暴力法没有意义,不做讲解,首先抓住题干中的行(列)内有序,大不了这个有序就可以使用二分查找,同时也要认清楚线性有序,有序基本上必然和二分查找分不开了。 暴力求解 O ( n l g n ) O(nlgn) O ( n l g n )   首先来讲解暴力求解,如上分析,这个暴力求解不是指 O ( n 2 ) O(n^2) O ( n 2 )

例25:二分查找

人盡茶涼 提交于 2020-01-26 04:21:06
二分查找大一的时候是试图写过一次的,但当时因为还加了一种其他算法,所以也没有写出来,之后对它有了一种很难的感觉,但现在一看,其实也非常简单。它其实就是好像电气工程师找电线断点一样,对半找,理论上最快。哎,我实在不知道这算法的思想该怎么去说,所以直接上步骤,后面接代码。 1.直接从中间的元素开始找,此元素与要找的值做比较,有三种情况,相等,大于和小于,相等则记录此元素位置并返回true结束函数,大于则缩小范围,让右边界等于此元素的位置减一,小于则让左边的边界等于此元素位置加一。 2.循环此过程直到左边界大于右边界跳出,此时其中始终没有元素与要找的值相等,所以代表未找到,返回false结束函数。 代码如下: 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 bool BinarySearch(int *pArray,int nCount,int *pCount,int numAnswer) 5 { 6 int low = 0,high = nCount-1; 7 while(low <= high) 8 { 9 int middle = low + (high-low)/2; 10 if(pArray[middle] == numAnswer) 11 { 12 *pCount = middle+1; 13 return true; 14 } 15

浅谈二分算法

我的梦境 提交于 2020-01-25 22:08:57
二分算法 程序或算法的时间复杂度 基本概念 一个程序或算法的时间效率,也称“时间复杂度”,有时简称“复杂度” 复杂度常用大写字母 O O O 和小写字母 n n n 来表示, n n n 代表问题的规模 时间复杂度是用算法运行过程中,某种时间固定的操作需要被执行的次数和 n n n 的关系来衡量的。在无序数列中查找某个数,复杂度是 O ( n ) O(n) O ( n ) 。 计算复杂度的时候,只统计执行次数最多的( n n n 足够大时)那种固定操作的次数。比如某个算法需要执行加法 n 2 n^2 n 2 次,除法 n n n 次,那么就记其复杂度是 O ( n 2 ) O(n^2) O ( n 2 ) 的。 复杂度有“平均复杂度”和“最坏复杂度”两种。两者可能一致,也可能不一致。一般情况下,只需考虑“平均复杂度”,只有在要求极为严格的情况下,才需要考虑“最坏复杂度” 如果复杂度是多个 n n n 的函数之和,则只关心随 n n n 增长增长得最快的那个函数 O ( n 2 + n 3 ) = > O ( n 3 ) O(n^2+n^3)=>O(n^3) O ( n 2 + n 3 ) = > O ( n 3 ) O ( 2 n + n 2 ) = > O ( 2 n ) O(2^n+n^2)=>O(2^n) O ( 2 n + n 2 ) = > O ( 2 n ) O ( n

剑指offer-旋转数组的最小数字-JavaScript

家住魔仙堡 提交于 2020-01-25 08:59:37
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为 1。 NOTE:给出的所有元素都大于 0,若数组大小为 0,请返回 0。 解法 1:暴力法 遍历一次,直接找到比较出最小的数字。 时间复杂度是 O(N),空间复杂度是 O(1)。 // 原文地址:https://xxoo521.com/2019-12-24-xuan-zhuan-shu-zu/ // ac地址:https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba /** * @param {number[]} rotateArray */ function minNumberInRotateArray ( rotateArray ) { const length = rotateArray . length ; if ( ! length ) { return 0 ; } return Math . min ( ... rotateArray ) ; } 解法 2: 二分查找 专注前端与算法的系列干货分享,欢迎关注(¬‿¬): 「微信公众号: 心谭博客 」| xxoo521.com |

“珠玑之椟”系列简介与索引

主宰稳场 提交于 2020-01-25 06:50:28
  二分查找是《编程珠玑》作者很喜爱的一个话题,之前我曾经专门写了一篇博文: 如何写出正确的二分查找?——利用循环不变式理解二分查找及其变体的正确性以及构造方式 ,在这里将换几个角度,继续探讨二分查找的相关内容,以及与它联系紧密的分治法和排序思想。     目录 二分思想和分治法 在O(n)时间内从数组x[0...n-1]中找出第k个最小的元素 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数 扩展:给定包含43亿个32位整数,找出至少出现两次的整数 其他:单侧二分查找、求平方根和方程的解 排序思想 给定一个英语字典,找出所有变位词集合 给定一个n元实数集合、一个实数t和一个整数k,确定是否存在一个元素之和不超过t的k元子集 二分思想和分治法   如果你对概念很敏感,会马上意识到这两者的细微不同:二分搜索每次都要舍弃一半,从留下的一半中寻找目标;而分治法把一个大问题分成两个或多个小问题,递归地求这些小问题的解,最后再把它们小心谨慎的合并起来,并且要仔细考虑合并时产生的新的情况。这当然没有错,但你也马上会从这里意识到两者的巨大联系。就拿选取数组中第k个最小的数的算法来说,有一个版本便是从快速排序中修改而来:划分后,舍弃掉不存在的区间,对剩余部分迭代(后文将进行讲解),而快速排序是分治法的典型代表。   正式地把这个问题叙述为: (习题11.9、

java算法-二分查找算法

时光怂恿深爱的人放手 提交于 2020-01-24 04:22:33
一、二分查找算法思想 又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。 二、图示说明 三、二分查找优缺点 优点是比较次数少,查找速度快,平均性能好; 其缺点是要求待查表为有序表,且插入删除困难。 因此,折半查找方法适用于不经常变动而查找频繁的有序列表。 使用条件:查找序列是顺序结构,有序。 四、代码实现 1.非递归方法 private static int binarySearch(int[] arr, int key) { int left = 0; int right = arr.length-1; int mid ; if (key < arr[left] || key > arr[right] || left > right){ return -1; } while(left < right){ mid = (left + right)/2; if (arr[mid] < key){ left = mid +1; }else if(arr[mid] > key){ right = mid - 1; }else { return mid ; } } return -1; } 2

lintcode-14-二分查找

旧城冷巷雨未停 提交于 2020-01-23 22:45:56
二分查找 给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1。 样例 在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2。 挑战 如果数组中的整数个数超过了2^32,你的算法是否会出错? 标签 二分法 数组 说明 普通的二分查找,数组中整数超过2^32会导致算法出错。 code class Solution { public: /** * @param nums: The integer array. * @param target: Target number to find. * @return: The first position of target. Position starts from 0. */ int binarySearch(vector<int> &array, int target) { // write your code here int size = array.size(); int low = 0, high = size-1, mid = (high + low) / 2; int find = -1; if(array[low]>target || array[high]<target) {