0
点赞
收藏
分享

微信扫一扫

打卡代码随想录Day1

杰克逊爱学习 2022-03-11 阅读 42

今天做的题目是有关二分查找的:

1.二分查找基本题目(力扣704):

在以前的基础上,考虑给定值比数组中最小的小或最大的大的情况。

public int search(int[] nums, int target) {
    int low = 0;
    int high = nums.length-1;
    int result;
    if((target<nums[0])||(target>nums[nums.length-1]))
        return -1;
    while ((nums[(low+high)/2] != target)&&(low<=high))
    {
        if(nums[(low+high)/2]<target){
            low = (low+high)/2+1;
        }
        else
            high = (low+high)/2-1;
    }
    if (low>high)
        return  -1;
    else
        return (low+high)/2;
}

2.二分查找+插入位置(力扣35):

题目要求在O(logn)的时间复杂度内完成,因此考虑二叉树结构,采用二分查找;若不在则返回插入位置,若存在则插到相同元素之前。

public int searchInsert(int[] nums, int target) {
    if(target<nums[0])
        return 0;
    if(target>nums[nums.length-1])
        return nums.length;
    int low = 0;
    int high = nums.length-1;
    while ((nums[(low+high)/2])!=target&&(low<=high))
    {
        if (nums[(low+high)/2]<target)
            low = (low+high)/2+1;
        else
            high = (low+high)/2-1;
    }
    //根据存在不存在,分别返回
    if(low>high)
        return (low+high)/2+1;
    else
        return (low+high)/2;
}

3.二分查找提升题(力扣34)

题目同样要求在O(logn)的时间复杂度内完成,继续选择二叉树结构,由于数组升序,选择二分查找。要注意数组越界问题。

    public int[] searchRange(int[] nums, int target) {
//        if(nums.length == 0)
//            return new int[]{-1,-1};
        if((nums.length == 0)||(target<nums[0])||(target>nums[nums.length-1]))
            return new int[]{-1,-1};
        int low = 0;
        int high = nums.length-1;
        int i,j;//用来指向目标值在数组中的开始和结束位置
        while (((nums[(low+high)/2])!=target) && (low<=high)){
            if(nums[(low+high)/2] < target)
                low = (low+high)/2+1;
            else
                high = (low+high)/2-1;
        }
        if (low>high)
            return new int[]{-1,-1};
        else {
             i  = (low+high)/2;
             j =  (low+high)/2;
             while ((i>0)&&(nums[i-1] == target))
                 i--;
             while ((j<nums.length-1)&&(nums[j+1] == target))
                 j++;
            }
        return new int[]{i,j};
    }

4.二分查找应用题,x的平方根(力扣69)

当x大于1时,其平方根小于等于x/2,根据此,在1到x/2的区间内查找其平方根,属于二分查找的应用。同时避免数过大,将乘法变为除法,也要避免除以0。

public int mySqrt(int x) {
    if(x==0||x==1)
        return x;
    //low设置为1防止下面mid==0造成除0
    int low = 1;
    //当x>1时,其平方根小于等于这个数的一半
    int high = x/2;
    int mid = (low+high)/2;
    //防止mid的平方大于2^31-1,循环中采用除法
    while (low<=high){
        if(mid == x/mid)
            return mid;
        else if(mid>x/mid){
            high = mid-1;
            mid = (low+high)/2;
        }
        else{
            low = mid+1;
            mid = (low+high)/2;
        }
    }
    return mid;
}
5.二分查找应用题,跟完全平方有关(力扣367)
这里注意int类型的数运算完会向下取整(如2 == 5/2 是成立的),因此将mid定义为double类型(2.0 == 5/2.0 是不成立的)

public boolean isPerfectSquare(int num) {
    if(num == 0 || num == 1)
        return true;
    int low = 1;
    int high = num/2;
    double mid = (low+high)>>1;
    while (low<=high){
        if(mid == num/mid)
            return true;
        else if(mid < num/mid)
        {
            low = (int)mid+1;
            mid = (low+high)>>1;
        }
        else {
            high = (int)mid-1;
            mid = (low+high)>>1;
        }
    }
    return false;
}
举报

相关推荐

0 条评论