二分查找

传说中的二分查找和快速排序

独自空忆成欢 提交于 2020-01-10 01:49:31
1、二分查找 /* 二分查找(折半查找),前提是在已经排好序的数组中 通过将待查找的元素与中间索引值对应的元素进行比较, 若大于中间索引值对应的元素,去右半部分查找,否则去左半部分查找 一次类推,知道找到位置 */ public class Test8 { public static void main ( String [ ] args ) { int [ ] nums = { 10 , 20 , 50 , 65 , 88 , 90 } ; //待查找数组 int index = binarySearch ( nums , 90 ) ; System . out . println ( index ) ; } //二分查找数列 public static int binarySearch ( int [ ] num , int key ) { int start = 0 ; //开始下标 int end = num . length - 1 ; //结束下标 while ( start <= end ) { int middle = ( start + end ) / 2 ; //>>>1 if ( num [ middle ] > key ) { end = middle - 1 ; } else if ( num [ middle ] < key ) { start =

二分查找(binary search)

∥☆過路亽.° 提交于 2020-01-09 16:51:06
1 二分查找的思想 每次将待查找元素与区间中间元素进行比较,将查找区间缩减为之前的一半,直到找到待查找元素或查找区间大小为0。 2 实现及关键点 2.1 关键点 1)循环退出条件 循环退出条件为low <= high,其中low为查找区间的下边界、high为上边界,而不是low < high。如果条件为low < high,那么当查找区间大小为1即low = high时,循环退出就无法与最后一个数据元素进行比较。 2)区间中间索引mid的取值 一般来说mid = (low + high) / 2,但是当low + high超出其数据类型范围时会造成溢出,所以这样的mid取值是不稳妥的。mid = low + (high - low) / 2这样减少了溢出的可能,或者mid = low + ((high - low) >> 1)这样通过位运算使得计算更加快速。 3)区间上下边界的更新 更新应为low = mid + 1、high = mid - 1而不是low = mid、high = mid。因为如果是low = mid、high = mid的更新方式,那么当查找区间为1时而最后的数据元素又不等于查找元素,那么程序会进入死循环。 2.2 实现 1 /*查找升序数组中是否存在数据元素num,存在返回其在数组中的位置,不存在则返回-1*/ 2 int BinarySearch(int*

数据结构和算法-二分查找

早过忘川 提交于 2020-01-09 16:50:47
本篇主要是<>教程笔记和python实现 原理: 在一个有序数组中, 不断比较中间位置的数和目标数的大小, 如果中间位置数比目标数大, 则再用同样办法比较前半部分, 否则比较后半部分. 如果没有找到目标数的位置, 返回None, 否则返回该数的位置. 因为是不断把数组分为一半一半的找, 所以时间复杂度是 O(logn) . 时间复杂度: O(logn) 实现 注: 要注意边界情况 # coding:utf-8 def binary_search(nums, value): low = 0 high = len(nums) - 1 # 注意是 <= while low <= high: mid = int((low + high) / 2) mid_value = nums[mid] # 注意 low 和 high 的取值, 防止发生死循环. 比如low=3, high=3 if mid_value < value: low = mid + 1 elif mid_value > value: high = mid - 1 else: return mid return -1 if __name__ == "__main__": nums = [1, 2, 3, 4, 5] print(binary_search(nums, 5)) 注意点 : 边界情况, 特别注意注释内容,

运用递归进行二分查找

℡╲_俬逩灬. 提交于 2020-01-07 20:44:02
package com.lm.digui; import java.util.Arrays; public class MergonQuery { public static void main(String[] args) { int merget[] = {2, 5, 39, 2, 2, 4, 2, 0, 74, 7, 5, 6, 3, 2, 1}; System.out.println(Arrays.toString(megerSort(merget))); } private static int[] megerSort(int[] merget) { if (merget.length < 2) { return merget; } int mid = merget.length / 2; int[] left = Arrays.copyOfRange(merget, 0, mid); int[] after = Arrays.copyOfRange(merget, mid, merget.length); return sertNumber(megerSort(left), megerSort(after)); } private static int[] sertNumber(int[] left, int[] after) { int[] result = new

leetcode704.二分查找

断了今生、忘了曾经 提交于 2020-01-06 20:06:54
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 示例 1: 输入 : nums = [ - 1 , 0 , 3 , 5 , 9 , 12 ] , target = 9 输出 : 4 解释 : 9 出现在 nums 中并且下标为 4 示例 2: 输入 : nums = [ - 1 , 0 , 3 , 5 , 9 , 12 ] , target = 2 输出 : - 1 解释 : 2 不存在 nums 中因此返回 - 1 提示: 你可以假设 nums 中的所有元素是不重复的。 n 将在 [1, 10000]之间。 nums 的每个元素都将在 [-9999, 9999]之间。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-search 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 完整代码 基本思想 朴实的二分查找 循环中的查找范围[left,right],循环结束的条件:left+1==right,left比right大1 class Solution { public : int search ( vector < int > & nums , int target

离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers

感情迁移 提交于 2020-01-05 03:07:39
题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问。还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前花开的数量,放张图易理解: 还有一种做法用尺取法的思想,对暴力方法优化,对询问点排序后再扫描一遍,花开+1,花谢-1。详细看代码。 收获:一题收获很多:1. 降低复杂度可以用二分 2. 线段计数问题可以在端点标记1和-1 3. 离散化+线段树 终于会了:) ( 听说数据很水? ) 代码1:离散化+线段树 /************************************************ * Author :Running_Time * Created Time :2015-8-25 8:55:54 * File Name :F.cpp ************************************************/ #include <cstdio> #include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string> #include <vector> #include <queue>

LeetCode33 搜索旋转排序数组

不问归期 提交于 2020-01-04 20:43:39
问题描述 :假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 例:输入: nums = [4,5,6,7,0,1,2], target = 0;输出: 4 注: 你可以假设数组中不存在重复的元素。 你的算法时间复杂度必须是 O(log n) 级别 思路 : 二分查找 由于为升序数组旋转后形成,利用此结构,分析所有情况 令left指向查找序列最左元素,right为最右,mid为中间元素 当nums[left] < nums[right]时,此时未旋转,有两种情况。 nums[left] ≤ target ≤ nums[mid],向前寻找 nums[mid] ≤ target ≤ nums[right],向后寻找 当nums[left] > nums[right]时,发生旋转,有四种情况。 nums[left] > nums[mid],旋转在前 nums[mid] ≤ target ≤ nums[right],向后寻找 target ≤ nums[mid] or target ≥ nums[left],向前寻找 nums[left] < nums[mid],旋转在后 nums[left] ≤

由二分查找算法学习算法的时间复杂度

醉酒当歌 提交于 2020-01-02 23:57:43
二分查找 二分查找是一种算法,其输入是一个 有序 的元素列表和要查找的元素。如果要查找的元素包含在列表中,二分查找返回其位置;否则返回null。 数据 函数形参:列表: xlist ,要查找的值: item 查找范围的索引: low ~ high 要去的索引: mid ,猜测的值: guess 算法 跟踪要查找的列表部分——开始时为整个列表 每次都检查中间的元素 xlist[mid] 如果猜的数字小了,就相应地修改 low , 如果猜的数字大了,就修改 high , 猜对了返回 mid ,否则列表 xlist 里没有要查找的值 iem ,返回 None 函数代码 def binsearch ( xlist , y ) : #注意list不能直接做形参 low = 0 high = len ( xlist ) - 1 while low <= high : mid = ( low + high ) / 2 mid = round ( mid ) #一定要取整 guess = xlist [ mid ] if guess == y : return mid if guess > y : high = mid - 1 else : low = mid + 1 return None 调用函数 import sys sys . path . append ( r "D:\python

【算法•日更•第一期】查找算法:简单实现二分

旧巷老猫 提交于 2019-12-30 22:40:17
▎二分 ☞ 『算法思想』   二分也就是 二分查找 ,又叫 折半查找 。这种算法正如其名,每一次都要分一半。废话不多说,直接抛砖引玉: Q:现在来思考一个问题:在一千以内我已经心中想好了一个数(不耍赖),你可以随意询问我一个数,我只会说大了、小了和猜对了,想必你一定玩过,那么请问怎样询问才能使用次数最少?   Answer:   其实有常识的人都知道,第一次说500;第二次说(第一次大了)250或(第一次小了)750;第三次125、375、625或875……以此类推。每一次都要砍一半询问,这样无疑不需要每个数都被查找一遍。如果你这样干过,那么可以说你已经会了二分的思想了。可能我没有说清楚,那么就再举个例子吧:(我心里想着666) A:500? B:小了 A:750? B:大了 A:625? B:小了 A:687? B:大了 A:656? B:小了 A:671? B:大了 A:663? B:小了 A:667? B:大了 A:665? B:小了 A:666? B:猜对了 ☞ 『算法复杂度分析』   由于每一次都会分掉一半,因此时间复杂度就是O(log n)。   形象一些说明就是最多查找n以2为底数的 对数 次。    对数 : 在数学中,对数是对求幂的逆运算,正如除法是乘法的倒数,反之亦然。 (copy自百度)比如说n=1024,log 1024= 10 ,因为2 10 =1024。

<查找算法> 二分查找BinarySearch

廉价感情. 提交于 2019-12-30 22:39:48
1 #include<iostream> 2 using namespace std; 3 4 int BinarySearch(int arr[],int begin,int end,int num) 5 { 6 if(arr == NULL || begin < 0 || end < 0 || begin >= end) return -1; 7 8 int mid = (begin+end)/2; 9 if(arr[mid] == num) 10 return mid; 11 else if(arr[mid] > num) 12 BinarySearch(arr,begin,mid-1,num); 13 else if(arr[mid] < num) 14 BinarySearch(arr,mid+1,end,num); 15 } 16 17 int main() 18 { 19 int arr[] = {2,4,11,13,20,24,33,56,78,91}; 20 cout << "找到num在数组中的下标为:" << BinarySearch(arr,0,sizeof(arr)/sizeof(arr[0])-1,78); 21 22 system("pause"); 23 return 0; 24 } 来源: https://www.cnblogs.com