算法数组专题

1.二分查找

y总板子,这里是acwing二分查找的题解。分为两个板子

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc =  new Scanner(System.in);
        int num = sc.nextInt();
        int count = sc.nextInt();
        
        int[] arr = new int[num];
        for(int i = 0; i < num;i++){
            arr[i] = sc.nextInt();
        }
        
        while(count-- > 0){
            int target = sc.nextInt();
            int l = 0, r = num -1;
            while(l < r){
                int mid = l + r >> 1;
                if(arr[mid] >= target)
                    r = mid;
                else
                    l = mid + 1;
            }
            if(arr[l] != target){
                System.out.println("-1 -1");
            }else{
                System.out.print(l + " ");
                l = 0 ; r = num - 1;
                while(l < r){
                    int mid = l + r + 1 >> 1;
                    if(arr[mid] <= target)
                        l = mid ;
                    else
                        r = mid - 1;
                }
                System.out.println(l);
            }
        }
       
    }
}

第一题,简单二分查找:力扣704

直接套用第一个板子,找不到时返回-1即可

class Solution {
    public int search(int[] nums, int target) {
        int l = 0, r = nums.length -1;
        while(l < r){
            int mid = l + r >> 1;
            if(nums[mid] >= target){
                r = mid ;
            }else{
                l = mid + 1;
            }
        }
        if(nums[l] != target) {
            return -1;
        }
        return l;
    }
}

第二题,搜索插入位置:力扣35

这里也是直接套用第一个板子,先判断目标是否比数组的数都大。

class Solution {
    public int searchInsert(int[] nums, int target) {
        int l = 0, r = nums.length - 1;
        if(nums[r] < target){
            return nums.length;
        }
        while(l < r){
            int mid = l + r >> 1;
            if(nums[mid] >= target){
                r = mid;
            }else{
                l = mid + 1;
            }
        }
        return l;
    }
}

第三题,在排序数组中查找元素的第一个和最后一个位置:力扣34

这题直接套用两个板子,完全符合y总的板子,但是需要注意特殊情况的处理:比如先判断是否为0;还有先判断第一个数是否为-1,如果是-1就直接返回

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int len = nums.length;
        if(len ==  0){
            return new int[]{-1,-1};
        }
        int f = first(nums,target);
        if(f == -1){
            return new int[]{-1,-1};
        }
        int la = end(nums,target);
        return new int[]{f,la};
    }

    private int first(int[] nums, int target){
        int l =0, r = nums.length -1;
        while(l < r){
            int mid = l + r >> 1;
            if(nums[mid] >= target){
                r = mid;
            }else{
                l = mid + 1;
            }
        }
        if(nums[l] != target){
            return -1;
        }
        return l;
    }

    private int end(int[] nums,int target){
        int l =0, r = nums.length -1;
        while(l < r){
            int mid = l + r + 1 >> 1;
            if(nums[mid] <= target){
                l =  mid;
            }else{
                r = mid - 1;
            }
        }
        return l;
    }
}

第四题,x的平方根:力扣69

这种题型与前面的不一样,这种是套用第二个板子,而且这种题型是针对数进行二分,前面都是针对数组。

需要注意。在处理乘法时转换为除法。

class Solution {
    public int mySqrt(int x) {
        int l  =0 , r = x;
        while(l < r){
            int mid = l + r + 1 >> 1;
            if(mid <= x / mid){
                l = mid;
            }else{
                r = mid - 1;
            }
        }
        return l;
    }
}

第五题,有效的完全平方数:力扣367

这个题跟上面的题差不多,遇到平方,平方跟,使用第二个板子即可

class Solution {
    public boolean isPerfectSquare(int num) {
        int  l =0, r = num;
        while(l < r){
            int  mid = l + r + 1 >> 1;
            if(mid <= num / mid){
                l = mid;
            }else{
                r = mid - 1;
            }
        }
        return l * l == num ;
    }
}

总结:平方数时使用第二个板子;求两个数时,两个板子一起使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值