二分法

代码随想录之二分法

 704.二分法查找

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

分析:如给定一个数组{1,2,3,4,5,6},给定一个target =3,进行查找

方法一:暴力解法,利用for循环进行遍历

class Solution {
    public int[] searchRange(int[] nums, int target) {
    for(int i =0; i < nums.length; i++){
      if (nums[i] == target){ return   i;} 
      else {return -1;}
    }
}
}

 

方法二:二分查找

第一种 左闭右闭[left,right]

复制代码

class Solution {
    public int search(int[] nums, int target) {
        if (target < nums[0] || target > nums[nums.length - 1]) {
            return -1;
        }
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid - 1;
        }
        return -1;
    }
}
          
复制代码

   左闭右闭时,while( left < = right) 当left = right 有意义 。

 int mid = left + (right - left) / 2 的作用是:防止数据溢出。

 当 nums[mid]>target 说明target位于mid的左边,right = mid - 1;区间变为[left,mid - 1]

 当 nums[mid]<target 说明target位于mid的右边,left = mid + 1;区间变为[mid + 1,right]

 

第二种:左闭右开[left,right)

复制代码

class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid;
        }
        return -1;
    }
}
   
复制代码

 当 nums[mid]>target 说明target位于mid的左边,right = mid - 1;区间变为[left,mid )

 当 nums[mid]<target 说明target位于mid的右边,left = mid + 1;区间变为[mid + 1,right)

 

35.搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

有四种情况,target小于nums[0]在数组前,target大于nums[0]小于nums[nums.length-1]但没有对应值,target在范围内有对应值,target大于nums[nums.length-1]

 

复制代码
class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = left + (right - left) / 2;
            if(nums[mid] == target){
                return mid;
            } else if(nums[mid] > target){
                right = mid - 1;
            } else if(nums[mid] < target){
                left = mid + 1;
            }
         
        }
             return right + 1;
    }
}
复制代码

 return right +1的原因:当最后一次进行时 left = right =mid。如果(nums[mid] > target) 说明位置应该放在mid(也可以说是left或right)这个地方,但是后面进行了right =mid -1;则此时的位置应该是left或者right+1;

           如果(nums[mid] < target) ,说明结点在mid后面即mid+1处,后面对right也应该+1,则此时位置可以用left或者right+1表示。

 

69.x的平方根

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

复制代码
class Solution {
    public int mySqrt(int x) {
        int left = 0;
        int right = x;
     int temp = 0;
while (left <= right){ int mid = left + (right - left) / 2; long square = (long) mid * mid; if (square > x){ right = mid - 1; } else (square <= x){ temp = mid;
left
= left + 1; } } return temp; } }
复制代码

 

posted @   NOE42  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示