前言

之前面试准备秋招,重新翻起了《编程之美》。在第三章节看到了一道关于二分搜索的讨论,觉得有许多细节是自己之前也没怎么特别注意地方,比如二分搜索的初始条件,转化、终止条件之类的。

问题

找出一个有序(字典序)字符串数组 arr 中值等于字符串v的元素的序号,如果有多个元素满足这个条件,则返回其中序号最大的。

分析

如果去掉“返回序号最大的”,则标准的二分解法。但是数据中有重复元素,要求返回序号序号最大的元素序号。

以下是有BUG的解法:


int bisearch(int** arr, int b, int e, int* v)
{
int minIndex = b, maxIndex = e, midIndex;
while(minIndex < maxIndex)
{
midIndex = (minIndex + maxIndex) / 2;
if(strcmp(arr[midIndex], v) <=0)
midIndex = minIndex;
else
midIndex = maxIndex - 1;
}
if(!strcmp(arr[maxIndex], v))
return maxIndex;
else
return -1;
}
  • 可能存在上溢出
midIndex = (minIndex + maxIndex) / 2;

咋一眼看去没什么大的问题,但是极端情况下可能导致错误。如果这是个32位的程序,32位有符号整数可以标识的范围-2^31 ~ 231,如果minIndex+maxIndex恰好超过了232,就会导致上溢出,此时midIndex变成负数。

想象一下,当minIndex=2, maxIndex=3, 而arr[minIndex] <= v时,midInde将始终等于minIndex,进入死循环。

正确解法

int bisearch(int** arr, int b, int e, int* v)
{
int minIndex = b, maxIndex = e, midIndex;
while(minIndex < maxIndex - 1)
{
midIndex = minIndex + (maxIndex - minIndex) / 2;
if(strcmp(arr[midIndex], v) <=0)
midIndex = minIndex;
else
midIndex = maxIndex;
}
if(!strcmp(arr[maxIndex], v))
return maxIndex;
else if(!strcmp(arr[maxIndex], v))
return minIndex;
else:
return -1;
}

扩展问题

给定一个有序(不降序)数组arr:

  • 求任意一个使得arr[i]等于v,不存在则返回-1
  • 求最小的i使得arr[i]等于v,不存在则返回-1
  • 求最大的i使得arr[i]等于v,不存在则返回-1
  • 求最大的i使得arr[i]小于v,不存在则返回-1
  • 求最小的i使得arr[i]大于v,不存在则返回-1

数据结构与算法--二分搜索(binary search)的更多相关文章

  1. 算法与数据结构基础 - 折半查找(Binary Search)

    Binary Search基础 应用于已排序的数据查找其中特定值,是折半查找最常的应用场景.相比线性查找(Linear Search),其时间复杂度减少到O(lgn).算法基本框架如下: //704. ...

  2. LeetCode算法题-Binary Search(Java实现)

    这是悦乐书的第297次更新,第316篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第165题(顺位题号是704).给定n个元素的排序(按升序)整数数组nums和目标值,编 ...

  3. 《算法导论》习题2.3-5 二分搜索 Binary Search

    地球人都知道“二分查找”,方法也非常简单,但是你能不能在10分钟内写出一个没有bug的程序呢? 知易行难,自己动手写一下试一试吧. public class BinarySearch { public ...

  4. 第二十六篇 玩转数据结构——二分搜索树(Binary Search Tree)

          1.. 二叉树 跟链表一样,二叉树也是一种动态数据结构,即,不需要在创建时指定大小. 跟链表不同的是,二叉树中的每个节点,除了要存放元素e,它还有两个指向其它节点的引用,分别用Node l ...

  5. 二分搜索 - Binary Search

    二分搜索是一种在有序数组中寻找目标值的经典方法,也就是说使用前提是『有序数组』.非常简单的题中『有序』特征非常明显,但更多时候可能需要我们自己去构造『有序数组』.下面我们从最基本的二分搜索开始逐步深入 ...

  6. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  7. 算法与数据结构基础 - 二叉查找树(Binary Search Tree)

    二叉查找树基础 二叉查找树(BST)满足这样的性质,或是一颗空树:或左子树节点值小于根节点值.右子树节点值大于根节点值,左右子树也分别满足这个性质. 利用这个性质,可以迭代(iterative)或递归 ...

  8. 二分搜索(Binary Search)

    当我们在字典中查找某个单的时候,一般我们会翻到一个大致的位置(假设吧,翻到中间位置),开始查找.如果翻到的正好有我们要的词,那运气好,查找结束.如果我们要找的词还在这个位置的前面,那我们对前面的这一半 ...

  9. 数据结构之Binary Search Tree (Java)

    二叉查找树简介 二叉查找树(Binary Search Tree), 也成二叉搜索树.有序二叉树(ordered binary tree).排序二叉树(sorted binary tree), 是指一 ...

随机推荐

  1. IDEA2019.3激活使用

    IDEA2019.3激活使用 1.下载idea: https://www.jetbrains.com/idea/download/    下载 .exe或者.Zip都可以 2. 启动:点击下载好的id ...

  2. UTF-8 AND UTF-8 without BOM(遇到了这个问题 郁闷了会儿)

    两者的区别: Unicode规范中有一个BOM的概念.BOM——Byte Order Mark,就是字节序标记.在这里找到一段关于BOM的说明: 在UCS 编码中有一个叫做"ZERO WID ...

  3. 让vscode支持WePY框架 *.wpy

    WePY框架的.wpy 文件在微信开发者工具中无法打开,这里使用vscode 打开,并安装vetur 和vetur-wepy  插件即可

  4. coding++:error 阿里云 Redis集群一直Waiting for the cluster to join....存在以下隐患

    1):Redis集群一直Waiting for the cluster to join... 再次进行连接时首先需要以下操作 1.使用redis desktop Manager连接所有节点 调出命令窗 ...

  5. Python语法元素分析

    缩进 1个缩进 = 4个空格 用以在Python中标明代码的层次关系 缩进是Python语言中表明程序框架的唯一手段 注释 注释:程序员在代码中加入的说明信息,不被计算机执行 注释的两种方法: 单行注 ...

  6. PTA数据结构与算法题目集(中文) 7-3

    PTA数据结构与算法题目集(中文)  7-3 树的同构 给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的.例如图1给出的两棵树就是同构的,因为我们把其中一 ...

  7. 【php】日期时间

    一. 日期时间: a) 这是一块非常重要的内容,我们在windows当中,或者是将来要接触的定时器也好,都是需要使用到这一块内容的!二. PHP当中的日期时间: a) 时间戳:time()可以获取时间 ...

  8. k8s集群搭建笔记(细节有解释哦)

    本文中所有带引号的命令,请手动输入引号,不知道为什么博客里输入引号,总是自动转换成了中文 基本组成 pod:k8s 最小单位,类似docker的容器(也许) 资源清单:资源.资源清单语法.pod生命周 ...

  9. go 基本包

    像 fmt.os 等这样具有常用功能的内置包在 Go 语言中有 150 个以上,它们被称为标准库,大部分(一些底层的除外)内置于 Go 本身 unsafe: 包含了一些打破 Go 语言“类型安全”的命 ...

  10. javascript入门 之 ztree(三 简单json数据)

    <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - Standard Data </TITLE& ...