代码随想录算法打卡 Day1

文章介绍了二分查找算法的基本原理,如何在有序数组中查找元素的位置,以及其在计算平方根和判断完全平方数中的应用。重点讨论了循环不变量和边界处理的技巧。
摘要由CSDN通过智能技术生成

数组 - 二分查找


二分查找的意义在于通过二分将遍历的复杂度O(n)降低为O ( log ⁡ 2 n ) ,故二分的优化意义大于对问题的解决意义

704.二分查找

若定义 target 是在一个在左闭右闭的区间里,也就是[left, right],则需要注意两点:

①while(left<=right):此时left==right是有意义的

if (nums[middle] > target) right 要赋值为 middle - 1:因为nums[middle]是不等于target的

代码实现为:

class Solution {
    public int search(int[] nums, int target) {
        int left = 0 , right = nums.length-1;
        while(left<=right){
            int middle = (left+right)/2;
            if(nums[middle]==target){
                return middle;
            }else if(nums[middle]>target){
                right = middle-1;//target在左区间[left,middle-1]
            }else{
                left = middle+1;//target在右区间[middle+1,right]
            }
        }
        return -1;
    }
}

35.搜索插入位置

看到有序数组,考虑能否使用二分法解决问题,注意遵循循环不变量原则

代码实现为:

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0, right = nums.length-1;
        while(left<=right){
            int middle = (left+right)/2;
            if(nums[middle]==target){
                return middle;
            }else if(nums[middle]<target){
                left = middle+1;
            }else{
                right = middle-1;
            }
        }
        return left;//也可写right+1,包含了三种插入情况,分别是目标值在数组之前、之后以及中间
    }
}

34. 在排序数组中查找元素的第一个和最后一个位置

采用二分法去寻找左边界和右边界

class Solution {
public int[] searchRange(int[] nums, int target) {
        int rightBorder = getRightBorder(nums,target);
        int leftBorder = getLeftBorder(nums,target);
        //target超出数组(包含之前和之后)
        if(rightBorder==-2 || leftBorder==-2){
            return new int[]{-1,-1};
        }
        //数组中存在target
        if(rightBorder-leftBorder>1){
            return new int[]{leftBorder+1,rightBorder-1};
        }
        //target在数组范围内,但是没有相等的值
        return new int[]{-1,-1};

    }
    private int getRightBorder(int[] nums,int target){
         //找右边界
         int left = 0,right = nums.length-1;
       int rightBorder = -2;
        while(left<=right){
            int middle = (left+right)/2;
            if(nums[middle]>target){
                right = middle-1;
            }else{
                left = middle+1;
                rightBorder = left;
            }
        }
        return rightBorder;
    }
    private int getLeftBorder(int[] nums,int target){
        //找左边界
        int left = 0,right = nums.length-1;
        int leftBorder = -2;
        while(left<=right){
            int middle = (left+right)/2;
            if(nums[middle]<target){
                left = middle+1;
            }else{
                right = middle-1;
                leftBorder = right;
            }
        }
        return leftBorder;
    }
}

69.x的平方根

二分查找最经典的就是分三种情况等于、大于、小于,等于就是开方出来正好是整数,直接return middle;小于可能符合情况,因为是返回整型,所以用res记录下来,但是还得看看有没有比现在的大并且平方小于x的情况,接着赋值eft=middle+1;大于的话一定不符合,直接看左边的right=mid-1。

class Solution {
    public int mySqrt(int x) {
        int left = 0 , right = x, res = -1;
        while(left<=right){
            int mid = (left+right)/2;
            //注意mid*mid的类型转换,不转换可能会越界
            if((long)mid*mid==x){
                return mid;
            }else if((long)mid*mid>x){
                right = mid-1;
            }else{
                res = mid;
                left = mid+1;
            }
        }
        return res;
    }
}

367. 有效的完全平方数

class Solution {
    public boolean isPerfectSquare(int num) {
        int left = 0,right = num;
        while(left<=right){
            int mid = (left+right)/2;
            if((long)mid*mid==num){
                return true;
            }else if((long)mid*mid<num){
                left = mid+1;
            }else{
                right = mid-1;
            }
        }
        return false;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值