数据结构与算法-LeetCode练习二分查找应用

LeetCode 153. Find Minimum in Rotated Sorted Array

查找循环排序数组的最小元素(循环排序数组可以理解,一个环状数组(0,1,2,4,5,6,7),从其中一个元素断开后4,5,6,7,0,1,2)。

查找一个数组的最小原始,我们知道最简单的方式就是循环遍历其中数字,时间复杂度O(n)肯定能找到这个元素。我们看循环排序数组的结构,我们发现我们的数组还不完全是一个乱序数组,我们通过分析数组的规律,我们可以看的出,我们的数组还是局部有序的,我们的数组可以出现以下三种情况:

  1. 左边有序(如:2,4,5,6,7,0,1)
  2. 右边有序(如:6,7,0,1,2,4,5)
  3. 整个有序(如:0,1,2,4,5,6,7)

分析以上情况,我们知道我们的元素至少部分还是有序的,我们可以尝试二分法来查找最小元素,实现如下:

public static int findMin(int[] nums) {
        return findMin(nums, 0, nums.length - 1);
    }

    /*
     * 二分查找的实现主体
     */
    public static int findMin(int[] arr, int left, int right) {
        if (left == right) {
            return arr[left];
        }
        int middle = (left + right) / 2;
        if (arr[left] <= arr[middle] && arr[right] <= arr[middle]) { //当元素左边有序的情况
            return findMin(arr, middle + 1, right);
        } else if (arr[left] >= arr[middle] && arr[right] >= arr[middle]) { //当元素右边有序的情况
            return findMin(arr, left, middle);
        } else { //此时元素全部有序
            return arr[left];
        }
    }

LeetCode 33. Search in Rotated Sorted Array

查找循环排序数组的存在某个元素,返回该元素的位置(索引),如果不存在该元素,就返回-1.

public static int findNums(int[] nums, int target) {
        return findNums(nums, 0, nums.length - 1, target);
    }

    /*
     * 二分查找的实现主体
     */
    public static int findNums(int[] arr, int left, int right, int target) {
        if (left > right) {
            return -1;
        }
        int middle = (left + right) / 2;
        if (arr[left] == target) { //当前查找部分的left元素大小等于目标数字
            return left;
        }
        if (arr[right] == target) //当前查找部分的right元素大小等于目标数字
            return right;
        if (arr[middle] == target) { //当前查找部分的middle元素大小等于目标数字
            return middle;
        }
        if (arr[left] < arr[middle] && arr[right] < arr[middle]) { //当元素左边有序的情况
            if (arr[middle] > target) { //当中间元素大于目标元素
                //当最左边的元素大于目标元素,在右半部分查找,否则,在左半部分查找
                return arr[left] > target ? findNums(arr, middle + 1, right,
                        target) : findNums(arr, left, middle - 1, target);
            } else { //当中间元素小于目标元素
                return findNums(arr, middle + 1, right, target);
            }
        } else if (arr[left] > arr[middle] && arr[right] > arr[middle]) {//当元素右边有序的情况
            if (arr[middle] > target) { //当中间元素大于目标元素
                return findNums(arr, left, middle - 1, target);
            } else { //当中间元素小于目标元素
                //当最右边的元素大于目标元素,在右半部分查找,否则,在左半部分查找
                return arr[right] > target ? findNums(arr, middle + 1, right,
                        target) : findNums(arr, left, middle - 1, target);
            }
        } else { //当元素整个有序的情况
            if (arr[middle] > target) {
                return findNums(arr, left, middle - 1, target);
            } else {
                return findNums(arr, middle + 1, right, target);
            }
        }
    }

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 19:06:26

数据结构与算法-LeetCode练习二分查找应用的相关文章

数据结构与算法实践 之 二分查找初识

今天起,我要对数据结构和基本的算法进行一些简单的复习,并在复习的基础上对其进行深入的挖掘.这篇文章先对二分查找进行一个简要的复习,在之后的文章中会对其进行深入的学习. 二分查找又叫折半查找,是最基本的几种查找算法之一.简单的看,二分法查找主要应用于在一个有序数列中进行元素的查找,其基本思路是,先用我们要查找的元素与这个有序数列中的中间位置的元素进行比较(在此我们姑且称这个元素为"中间位置元素"吧,至于这个元素怎么求我在后面会详细说明),如果相等,则返回这个"中间位置元素&qu

【算法拾遗】二分查找递归非递归实现

转载请注明出处:http://blog.csdn.net/ns_code/article/details/33747953 本篇博文没太多要说的,二分查找很简单,也是常见常考的查找算法,以下是递归非递归的实现. 非递归实现: /* 非递归实现,返回对应的序号 */ int BinarySearch(int *arr,int len,int key) { if(arr==NULL || len<1) return -1; int low = 0; int high = len-1; while(l

算法——基础篇——二分查找

     二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.     首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功

Python 迭代器&amp;生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致 迭代器&

Leetcode题解——算法思想之二分查找

1. 求开方 2. 大于给定元素的最小元素 3. 有序数组的 Single Element 4. 第一个错误的版本 5. 旋转数组的最小数字 6. 查找区间 正常实现 Input : [1,2,3,4,5] key : 3 return the index : 2 public int binarySearch(int[] nums, int key) { int l = 0, h = nums.length - 1; while (l <= h) { int m = l + (h - l) /

算法:时间复杂度+二分查找法(Java/Go/Python)实现

导读 曾几何时学好数据结构与算法是我们从事计算机相关工作的基本前提,然而现在很多程序员从事的工作都是在用高级程序设计语言(如Java)开发业务代码,久而久之,对于数据结构和算法就变得有些陌生了,由于长年累月的码砖的缘故,导致我们都快没有这方面的意识了,虽然这种论断对于一些平时特别注重学习和思考的人来说不太适用,但的确是有这样的一个现象. 而在要出去面试找工作的时候,才发现这些基础都快忘光光了,所以可能就"杯具"了!实际上,对于数据结构和算法相关的知识点的学习,是程序员必须修炼的一门内功

python数据结构与算法 29-1 哈希查找

前面的章节中,我们利用数据集中元素的相对位置信息来提高查找算法的性能. 比方知道列表是有序的,能够使用二分查找.本节我们走得更远一些,创建一个数据结构,使得查找性能提高到O(1).称为哈希查找. 要做到这种性能,我们要知道元素的可能位置.假设每一个元素就在他应该在的位置上,那么要查找的时候仅仅须要一次比較得到有没有的答案,但以下将会看到.不是这么回事. 哈希表是这样一种数据集合,元素的保存的时候就存在easy找到位置上.哈希表表中每个位置,一般称为槽位,每个槽位都能保存一个数据元素并以一个整数命

算法题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

查找算法总结(二分查找/二叉查找树/红黑树/散列表)

1.二分查找 二分查找时,先将被查找的键和子数组的中间键比较.如果被查找的键小于中间键,就在左子数组继续查找,如果大于中间键,就在右子数组中查找,否则中间键就是要找的元素. /** * 二分查找 */ public class BinarySearch { public static int find(int[] array, int key) { int left = 0; int right = array.length - 1; // while (left <= right)不能改为<