二分查找总结及部分Lintcode题目分析 1

进行二分查找课程回顾与总结,包括以下几个方面,二分法的模板总结和解题思路、应用。

二分法模板总结classical binary search:

1. 必须要做的排除极端情况,也就是数组(用A表示)不存在即A == None或者 A为空,即len(A) == 0 的情况。

2. 二分法核心找的是mid值,并判断这个mid是否跟我们要找的target一致,或者和target之间的关系,所以要先判断start和end。为start和end赋值,start = 0, end = len(A) - 1

3. 之后就是要进行while循环,目的是用一次次的二分来找出是否存在target或者target的位置、范围等问题,条件是start + 1 < end来避免死循环

并有 mid = start + ( end - start ) / 2 来避免溢出

4. 判断A[mid] 与 target的关系,及采取怎样的赋值操作来保留有解的一半,即start == mid 或者 end == mid

5. 可能A[start] 与 A[end]的值与target相同,但是已经使 start + 1 < end 这个条件为False,所以在循环外还要判断这两个值是否和target一致。

6. 如果都不相等的话则返回空

下面,给出classical binary search的解法,这是简单而典型的binary search on index的问题

class Solution:
    # @param {int[]} A an integer array sorted in ascending order
    # @param {int} target an integer
    # @return {int} an integer
    def findPosition(self, A, target):
        # they are different
        if A is None or len(A) == 0:
            return -1
        # set start and end
        end = len(A) - 1
        start = 0
        # while loop, use start + 1 < end to avoid dead loop
        while (start + 1 < end):
            mid = start + ( end - start ) / 2
            if A[mid] == target:
                return mid
            elif A[mid] > target:
                # start..mid..end, target in start..mid
                end = mid
            else:
                start = mid
        if A[start] == target:
            return start
        if A[end] == target:
            return end
        return -1

由经典算法可以展开到the first position or the last position,都是binary search on index的典型例子,在这两种中即使找到了相应的元素为了判断是否是最开始或者最后的位置,在第四第五步要有所不同~以last position为例

while (start + 1 < end):
            mid = start + ( end - start ) / 2
            if A[mid] == target:
                start = mid
            elif A[mid] > target:
                # start..mid..end, target in start..mid
                end = mid
            else:
                start = mid
        if A[end] == target:
            return end
        if A[start] == target:
            return start
        

比较类似的像 search a 2D matrix 问题,只是把二维数组展开成一个一维数组,继续采用上面的二分法模板就可以解

class Solution:
    """
    @param matrix, a list of lists of integers
    @param target, an integer
    @return a boolean, indicate whether matrix contains target
    """
    def searchMatrix(self, matrix, target):
        if matrix is None or len(matrix) == 0:
            return False
        m = len(matrix)
        n = len(matrix[0])
        start = 0
        end = m * n - 1
        while(start + 1 < end):
            mid = start + (end - start) / 2
            line = mid / n
            column = mid % n
            if matrix[line][column] == target:
                return True
            elif matrix[line][column] < target:
                start = mid
            else:
                end = mid
        if matrix[(start / n)][(start % n)] == target:
            return True
        if matrix[(end / n)][(end % n)] == target:
            return True
        return False

search insert position 只要把握住二分法一个重要的特性,就是判断条件,就可以转化为找first position >= target 的问题

class Solution:
    """
    @param A : a list of integers
    @param target : an integer to be inserted
    @return : an integer
    """
    def searchInsert(self, A, target):
        # find the position whose value is equal or more than target
        # only consider no duplicates conditions
        if A is None or len(A) == 0:
            return 0
        start = 0
        end = len(A) - 1
        while(start + 1 < end):
            mid = start + (end - start) / 2
            if A[mid] >= target:
                end = mid
            else:
                start = mid
        if A[start] >= target:
            return start
        if A[end] >= target:
            return end        # a condition that the target is more than all of the elements in array
        if A[end] < target:
            return end + 1
        return -1
时间: 2024-10-29 01:00:02

二分查找总结及部分Lintcode题目分析 1的相关文章

二分查找总结及部分Lintcode题目分析 2

Search in a big sorted array,这个比之前的二分法模板多了一个很不同的特性,就是无法知道一个重要的条件end值,也是题目中强调的重点 The array is so big so that you can not get the length of the whole array directly~所以这里单独分析这个问题~ 一般涉及到sorted array,肯定可以的解决方法是for loop,然而for loop的复杂度是O(n),而且对于这个长度无法衡量的big

二分查找方法

问题描述: 二分查找指定的int数组 问题分析: 时间复杂度为O(logN) 代码实现: package c02; /**  * @project: DataStructureAndAlgorithmAnalysis  * @filename: BinarySearch  * @version: 0.10  * @author: Jimmy Han  * @date: 22:57 2015/7/7  * @comment: Test Purpose  * @result:  */ public 

HDU 3763 CD【二分查找】

解题思路:给出两个数列an,bn,求an和bn中相同元素的个数因为注意到n的取值是0到1000000,所以可以用二分查找来做,因为题目中给出的an,bn,已经是单调递增的,所以不用排序了,对于输入的每一个b[i],查找它在an数列中是否存在.存在返回值为1,不存在返回值为0 CD Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 627

二分查找里的upper bound与lower bound的实现与分析

1. 问题引入 最近参选了学堂在线的课程数据结构(2015秋).课程由清华大学的邓俊辉老师主讲,在完成课后作业时,遇到了这样一个题目范围查询.在这个题目中,我需要解决这样一个子问题:给定了一组已经排好序的整数集合A[0...n]和一组闭区间[L,R],求这个整数集合中落在这个区间中的点的个数.解决这个问题,我们很容易想到查找效率很高的二分查找,但是这又不是一般求key是否在一个数组里面的二分查找问题.对于区间左端点L,要找到数组里面大于或等于它的最小的元素的下标indexL.对于区间右端点R,要

LintCode刷题---二分查找

描述: 给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开         始),如果target不存在于数组中,返回-1. 样例 : 输入: [1, 2, 3, 3, 4, 5, 10], 3 输出: 2 样例解释:  3 第一次出现在第2个 解题: 难点分析: 注意数组中存在着重复数据, 而利用二分查找找出来的数据不一定是第一个, 数据需要检验. public int binarySearch(int[] nums,

『嗨威说』算法设计与分析 - 算法第二章上机实践报告(二分查找 / 改写二分搜索算法 / 两个有序序列的中位数)

本文索引目录: 一.PTA实验报告题1 : 二分查找 1.1 实践题目 1.2 问题描述 1.3 算法描述 1.4 算法时间及空间复杂度分析 二.PTA实验报告题2 : 改写二分搜索算法 2.1 实践题目 2.2 问题描述 2.3 算法描述 2.4 算法时间及空间复杂度分析 三.PTA实验报告题3 : 两个有序序列的中位数 3.1 实践题目 3.2 问题描述 3.3 算法描述 3.4 算法时间及空间复杂度分析 四.实验心得体会(实践收获及疑惑) 一.PTA实验报告题1 : 二分查找 1.1 实践

算法题16 二分查找及相关题目

二分查找思想就是取中间的数缩小查找范围,对应不同的题目变形,在取到中间数mid确定下一个查找范围时也有不同,左边界有的low=mid+1,也可能low=mid,右边界有的high=mid-1,也有可能high=mid. 对于一个排序数组来说二分查找的时间复杂度是O(logn) 1. 二分查找法 1 int BinarySearch(int arr[],int len,int target) 2 { 3 if (arr==NULL||len<=0) 4 throw std::exception(&qu

lintcode——排序列表转换为二分查找树(链表,二叉排序树)

中等 排序列表转换为二分查找树查看运行结果 27% 通过 给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树 您在真实的面试中是否遇到过这个题? Yes 样例 标签 Expand 相关题目 Expand 思路: 这道题将排好序的链表转化为二叉排序树,即左子树<根节点<右子树 采用递归的方法,在链表上选取中间点作为根节点, 每次传入的参数为,需要创建的根节点的指针(这里由于要改变指针的值,所以要传入指针的指针),链表开始指针,结尾指针,链表结点个数( 这里传入了个数之后,就不

LintCode 14. 二分查找

题目:给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1. 样例 在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2. 挑战 如果数组中的整数个数超过了2^32,你的算法是否会出错? 解:标准的二分查找 注意,最后一个else即找到target,但是target的值在数组中有多个,应返回下标最小的一个(else里的while实现这一效果). class