#LeetCode每日打卡 --- day01 [ LeetCode.704 二分查找 && LeetCode.278 第一个错误版本 && LeetCode.35 搜索插入位置 ]

目录

题目:

一、二分查找  

二、第一个错误的版本

三、搜索插入位置

总结







题目:

        LeetCode704.二分查找

        LeetCode278.第一个错误的版本

        LeetCode35.搜索插入位置







一、二分查找  

  1. 解题思路:
    1. nums为升序数组, 比较nums[i]与target:                                                                              num[i] > target --- 在下标i的左侧寻找;                                                                            num[i] < target --- 在下标i的右侧寻找;                                                                            num[i] = target --- 返回下标i;
    2. 二分查找法:设置查找范围为[low,high],每次查找查找范围的中点mid,比较nums[mid]和target,相等返回i,不相等根据target与nums[mid]的大小缩小查找范围为一半;
    3. 返回值:在查找范围不为空的情况下(即,low<=high),查找到结果,返回target对应的下标(值相等时的mid);low>high时未查找到等值,target未在数组中,返回-1。
  2. 代码:
    class Solution {
        public int search(int[] nums,int target) {
            int low = 0, high = nums.length-1;
            while(low <= high){
                int mid = low + (high-low)/2; //不能用(low+high)/2形式,当low和high都是int,两个值的初始值都超过int限定大小的一半,那么low+high就会发生溢出,所以应该用low+(high-low)/2来防止求中值时候的溢出
                if(nums[mid] > target) {
                    high = mid - 1;
                } else if (nums[mid] < target) {
                    low = mid + 1;
                } else {
                    return mid;
                }   
            }
            return -1;
        }
    }
  3. 复杂度分析:
    1. 时间复杂度:每次查找会将查找范围缩小一半,时间复杂度为O(log n) ,n为数组长度
    2. 空间复杂度:O(1)

二、第一个错误的版本

  1. 解题思路:
    1. 在1111111...0000000...中查找第一个错误版本,正确版本之前的全为正确版本,错误版本之后的全为错误版本;
    2. 二分查找法:设置查找范围[low,high],最初范围[1,N],每次查找中间值mid,查找为正确版本时,结果在此版本右侧([low,mid]之间);查找为错误版本时,结果在此版本左侧([mid+1,high]之间);
    3. 返回值:直至low = high时,查找到结果,low和high均为返回值。
  2. 代码
    /* The isBadVersion API is defined in the parent class VersionControl.
          boolean isBadVersion(int version); */
    
    public class Solution extends VersionControl {
        public int firstBadVersion(int n) {
            int low = 1, high = n;
            while(low < high) {   
                int mid = low + (high - low) / 2;
                if(isBadVersion(mid)){
                    high = mid;
                } else {
                    low = mid + 1;
                }
          }
            return high;
        }
    }
  3. 复杂度分析
    1. 时间复杂度:每次查找会将查找范围缩小一半,时间复杂度为O(log n) ,n为数组长度
    2. 空间复杂度:O(1)

三、搜索插入位置

  1. 解题思路:
    1. 直接用二分查找法,不过要考虑目标值不存在于数组中的情况;
    2. 返回值:在查找范围不为空的情况下(即,low<=high),查找到结果,返回target对应的下标(值相等时的mid);low>high时未查找到等值,返回它将会被按顺序插入的位置(即最终的low值)。
  2. 代码
    class Solution {
        public int searchInsert(int[] nums, int target) {
            int low = 0, high = nums.length - 1;
            while(low <= high){
                int mid = low + (high - low) / 2;
                if(nums[mid] > target) {
                    high = mid - 1;
                } else if (nums[mid] < target) {
                    low = mid + 1;
                } else {
                    return mid;
                }
            }
            return low;
        }
    }
  3. 复杂度分析
    1. 时间复杂度:每次查找会将查找范围缩小一半,时间复杂度为O(log n) ,n为数组长度
    2. 空间复杂度:O(1)






总结

  1.         二分查找中,mid赋值时使用low+(high-low)/2,不使用(low+high)/2防止当low和high都是int型,且值都超过int的一半时,发生溢出。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值