`

二分查找算法小结

 
阅读更多
在做leetcode二分查找类型题目时写while条件总担心写错,也确实好几次都是得到Wrong Answer之后再修改对的。在做Search for a range一题时,虽然被Accept了,但看网上其他同学的解析并不是特别理解,终于下决心去好好研究下最经典的二分查找算法,搞清楚不同情况下为什么while条件写法不一样。很幸运,很快便找到一遍总结得很棒的博客:
http://blog.csdn.net/daniel_ustc/article/details/17307937
拜读后自己实现了下,实现过程中对while条件不同情况下为什么不一样理解得更深刻了。

实现的三个二分查找方法分别解决如下问题:
1)查找数组中target出现的下标,不存在返回-1
2)查找数组中target第一次出现的下标位置,若不存在返回-1
3)查找数组中target最后一次出现的下标位置,若不存在返回-1
PS: 数组升序排列,可能有重复元素
package org.work.basic.binarysearch;

import junit.framework.Assert;
import org.junit.Test;

public class BinarySearchCore {

    @Test 
    public void testBinarySearch() {
        int[] nums = {0,1,1,1,2};
        Assert.assertEquals(2, binarySearch(nums, 1));
        Assert.assertEquals(1, binarySearchFirst(nums, 1));
        Assert.assertEquals(3, binarySearchLast(nums, 1));
        int[] nums1 = {1};
        Assert.assertEquals(0, binarySearch(nums1, 1));
        Assert.assertEquals(0, binarySearchFirst(nums1, 1));
        Assert.assertEquals(0, binarySearchLast(nums1, 1));
        int[] nums2 = {1,1};
        Assert.assertEquals(0, binarySearch(nums2, 1));
        Assert.assertEquals(0, binarySearchFirst(nums2, 1));
        Assert.assertEquals(1, binarySearchLast(nums2, 1));
        
    }
    // 查找target在nums[]中的下标,若有重复,返回任意一个即可,若找不到返回 -1
    public int binarySearch(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if (target == nums[mid])
                return mid;
            else if (target < nums[mid])
                right = mid - 1;
            else 
                left = mid + 1;
        }
        return -1;
    }
    // 查找target在nums[]中第一次出现的下标,若找不到返回-1
    public int binarySearchFirst(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left < right) { // 此处不能有等号,否则可能在right=mid处死循环,考虑case:[1], 1
            mid = left + ((right - left) >> 1);
            if (target > nums[mid])
                left = mid + 1;
            else
                right = mid;
        }
        if (nums[left] == target)
            return left;
        return -1;
    }
    // 查找target在nums[]中最后一次出现的下标,若找不到返回-1
    public int binarySearchLast(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left + 1 < right) { // 循环只处理元素个数大于两个的情况,两个以下元素时可能在left=mid处死循环(两个元素时left==mid),考虑case:[1,1],1
            mid = left + ((right - left) >> 1);
            if (target < nums[mid])
                right = mid - 1;
            else
                left = mid;
        }
        if (nums[right] == target)
            return right;
        else if(nums[left] == target)
            return left;
        return -1;
    }
}

分享到:
评论

相关推荐

    查找算法和排序算法小结

    查找算法和排序算法小结 本文总结了常见的查找算法和排序算法,包括顺序查找、二分查找、选择排序、冒泡排序、二分排序、插入排序、希尔排序、堆排序、归并排序等。 一、查找算法 1. 顺序查找(Sequential Search...

    数据结-构查找算法二分查找二叉顺序数哈希查找

    二分查找,也称为折半查找,适用于有序的线性表,如数组。算法的基本思路是将查找区间不断减半,每次比较中间元素与目标值,如果目标值等于中间元素则查找成功,否则根据目标值与中间元素的大小关系缩小查找区间。...

    折半查找算法及matlab代码实现

    该算法的基本思想是通过不断将搜索范围减半来查找目标值,因此也被称为二分查找。与线性查找相比,折半查找在最坏情况下的时间复杂度为O(log n),而线性查找的时间复杂度为O(n)。 **折半查找算法步骤如下:** 1. *...

    PHP实现二维数组中的查找算法小结

    例如,对于完全有序的矩阵,可以考虑更高效的二分查找法;而对于无序的二维数组,线性查找可能是唯一的选择。同时,如果需要频繁查找操作,预处理数据,如构建索引,也能显著提升性能。 总的来说,了解和掌握不同...

    数据结构顺序查找

    实验小结时,应总结这两种查找算法的特点、优缺点和适用场景。顺序查找简单易懂,但效率较低,适合数据量小或者数据无序的情况;而二分查找虽然要求数据有序,但查找效率高,特别适合大数据量的查找操作。此外,还应...

    算法设计结课代码

    在本项目中,可能包含了如何利用分治思想来处理一些复杂问题,比如二分查找、矩阵链乘法等。 4. **回溯法**(Backtracking):回溯法是一种试探性的解决问题方法,当发现当前选择可能导致无法找到解时,会撤销选择...

    Delphi算法与数据结构 源码(上)

    这本书强调了查找算法(如顺序和二分查找),另外也重点介绍了排序算法(包括冒泡排序、插入排序、希尔排序、快速排序和堆排序),此外还提供了有关的优化技术。不仅如此,作者还介绍了散列和散列表、优先队列、状态...

    Delphi算法与数据结构 源码(下)

    这本书强调了查找算法(如顺序和二分查找),另外也重点介绍了排序算法(包括冒泡排序、插入排序、希尔排序、快速排序和堆排序),此外还提供了有关的优化技术。不仅如此,作者还介绍了散列和散列表、优先队列、状态...

    面试常考算法模板 Cheat Sheet V4.1.pdf

    根据给定文件的信息,我们可以总结出以下关于二分查找算法的知识点: ### 二分查找算法概述 二分查找算法是一种在有序数组中查找特定元素的高效算法。它的工作原理是通过将目标值与数组中间元素进行比较来不断缩小...

    Java数据结构和算法中文第二版

    递归的二分查找 汉诺(Hanoi)塔问题 归并排序 消除递归 一些有趣的递归应用 小结 问题 实验 编程作业 第7章 高级排序 希尔排序 划分 快速排序 基数排序 小结 问题 实验 编程作业 第8章 二叉树 为...

    C/C++常用算法手册.秦姣华(有详细书签).rar

    5.4.1 顺序表结构中的查找算法 145 5.4.2 链表结构中的查找算法 148 5.4.3 树结构中的查找算法 151 5.4.4 图结构中的查找算法 152 5.5 小结 153 第6章 基本数学问题 154 6.1 判断闰年 154 6.2 多项式计算 ...

    《算法设计与分析》实验报告:实验一(分治策略)

    1. **二分搜索**:该算法用于在有序数组中查找特定元素。首先,将数组分成两个大约相等的部分,然后比较中间元素与目标值,根据比较结果决定是在左半部分还是右半部分继续搜索。这个过程不断递归,直到找到目标元素...

    计算机算法题目与提示代码

    - **二分搜索**:是在有序数组中查找特定元素的一种高效算法。初始时,考虑整个数组,如果中间元素正好是要查找的元素,则搜索结束;如果中间元素大于目标值,则在数组的左半部继续搜索;反之,在右半部搜索。 - **...

    小甲鱼数据结构与算法课件+源码.zip_-baijiahao_expresschs_once4l3_小甲鱼 ppt_小甲鱼数据结

    典型的算法有排序(冒泡排序、选择排序、插入排序、快速排序、归并排序等)、搜索(线性搜索、二分搜索)、图的遍历(深度优先搜索DFS和广度优先搜索BFS)等。理解算法的时间复杂度和空间复杂度对于优化代码性能至关...

    Java数据结构和算法(第二版)

    递归的二分查找 汉诺(Hanoi)塔问题 归并排序 消除递归 一些有趣的递归应用 小结 问题 实验 编程作业 第7章 高级排序 希尔排序 划分 快速排序 基数排序 小结 问题 实验 编程作业 第8章 二叉树 为什么使用二叉树? ...

    算法引论:一种创造性方法.[美]Udi Manber(带详细书签).pdf

    全书共分12章:第1章到第4章为介绍性内容,涉及数学归纳法、算法分析、数据结构等内容;第5章提出了与归纳证明进行类比的算法设计思想;第6章到第9章分别给出了4个领域的算法,如序列和集合的算法、图算法、几何算法...

    华为OD机考小结+算法编程试题一遍过

    - 基础知识:字符串操作、数组、链表、队列和栈,排序、迭代、递归、二分查找。 - 进阶知识:树、堆、图论,DFS(含回溯算法)、BFS、贪心算法、动态规划。 5. **注意事项**: - 考试前关闭所有无关网页和程序,...

    实验七 查找技术的编程实现

    实验七的目的是让学生掌握查找技术的编程实现,包括但不限于顺序查找、二分查找以及哈希查找等方法。这是一个综合性的实验,它要求学生结合多种数据结构和算法,设计并实现具有实际应用价值的程序。 **1. 顺序查找*...

    c语言数据结构的小结

    查找算法包括顺序查找、二分查找和哈希查找等,它们在不同数据结构上表现出不同的效率。 学习C语言数据结构时,理解这些基本概念并动手实践是至关重要的。通过编写代码实现这些数据结构和算法,可以帮助深化理解,...

    算法个人总结

    这类问题可能包括查找特定模式、统计0和1的数量、或进行位翻转等操作。通过熟练掌握C语言中的字符串函数和位运算符,可以高效地解决这些问题。 #### 6. 字母图形绘制 绘制字母图形通常需要使用嵌套循环结构。例如,...

Global site tag (gtag.js) - Google Analytics