`

二分查找算法小结

 
阅读更多
在做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章 二叉树 为...

    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语言数据结构时,理解这些基本概念并动手实践是至关重要的。通过编写代码实现这些数据结构和算法,可以帮助深化理解,...

Global site tag (gtag.js) - Google Analytics