LeetCode704:二分查找

题目:

        给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

说明:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

一、个人分析思路:

        二分查找,老生常谈的话题,今天仔细地来分析一下这类题型。总体的思路为:

        设定左右两个边界L和R,还有一个中间量M,其中中间量M=floor(L+R)/2;

        当左边界的值L不超过R时,

               ①若当目标值小于中间量时,说明目标值在左侧;

               ②若当目标值大于中间量时,说明目标值在右侧;

               ③若当目标值等于中间量时,目标值即为所求。

        另外,对于中间量M=floor(L+R)/2,以java语言为例,如下有三种思路

                ①M=(L+R)/2;    //当l+r>Integer.MAX_VALUE,MAX_VALUE的值为20多亿,L+R的相加的结果会导致数值溢出。

                ②M=L+(R-L)/2;   //利用数学公式进行优化,可以避免方法一中的问题

                ③M=(L+R)>>1;   //利用移位运算符,向右移动1位,相比上述方法高效,且不用担心溢出问题。关于移位运算,我的这篇博客做了详细的论述。关于Java中的移位运算:左移<<,右移>>和无符号右移>>>_lollipop的博客-CSDN博客移位运算一、前备知识:计算机数据表示(原码、反码和补码)1.1、符号位1.2、对于正数1.3、对于负数1.4、举例二、移位运算2.1、举例2.2、分析2.3、代码验证一、前备知识:计算机数据表示(原码、反码和补码)1.1、符号位对于正数,符号位在最高位用0表示;对于负数,符号位在最高位用1表示;1.2、对于正数原码=反码=补码1.3、对于负数反码=原码的符号位不变,其他位按位取反;补码=反码+1;1.4、举例数值原码反码补码50000 01010000 01https://blog.csdn.net/xenian_xerus/article/details/121443633        上代码:

class Solution {
    public int search(int[] nums, int target) {
        int l=0,r=nums.length-1,m;
        while(l<=r){
            //方法一:当l+r>Integer.MAX_VALUE,会导致数值溢出
            // m=(l+r)/2;
            //方法二:利用数学公式进行优化,可以避免方法一中的问题
            // m=l+(r-l)/2;
            //方法三:利用移位运算符,向右移动1位,相比上述方法高效,且不用担心溢出问题
            m=(l+r)>>1;
            if(nums[m]>target){
                 r= m-1;  
            }else if(nums[m]<target){
                 l = m+1;
            }else{
                return m;
            }
        }
        return -1;
    }
}

         最后附上运行结果:

   

 

Guess you like

Origin blog.csdn.net/xenian_xerus/article/details/121549745