基础算法之二分查找--Java实现(上)--LeetCode题解:二分查找-在排序数组中查找元素的第一个和最后一个位置-搜索插入位置 -x 的平方根-山脉数组的峰顶索引

这里是Themberfue

二分查找 

· 二分查找是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

· 当然,二分查找也不一定就是只能在有序数组上进行,如果该数组满足 "二段性",则就可以使用二分查找算法。

二分查找

        题目解析

这题的就是在给定数组下找到 target 值。

        算法讲解 

· 使用暴力解法的时间复杂度是 O(N),但如果使用二分查找,那么时间复杂度将减为O(logN)

· 至于怎么使用最简单的二分查找我也就不多说了,直接上代码吧。

        编写代码 

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

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

        题目解析

target在数组中存在多次,找到其在数组元素起始位置和结束位置,返回即可。 

        算法讲解 

· 我们先处理左端点,如果此时mid对应的元素小于 target,说明它在 mid 的右边,left = mid + 1即可。

· 若是 mid对应的元素大于等于 target,说明它在 mid 的左边,但是它也可能就在 mid 的位

置,所以 right = mid。

· 我们处理右端点,如果此时 mid 对应的元素大于 target,说明它在 mid 的左边,right = mid - 1即可。

· 若是 mid 对应的元素小于等于 target,说明它在 mid 的右边,但是它也可能就在 mid 的位置,所以 left = mid。

        编写代码 

class Solution {
    public int[] searchRange(int[] nums, int target) {
        if (nums.length == 0) return new int[]{-1, -1};
        int[] ret = new int[2];
        int left = 0, right = nums.length - 1;
        // 处理左端点
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        ret[0] = nums[left] == target ? left : -1;

        left = 0; right = nums.length - 1;
        // 处理右端点
        while (left < right) {
            int mid = left + (right - left + 1) / 2;
            if (nums[mid] <= target) {
                left = mid;
            } else {
                right = mid - 1;
            }
        }
        ret[1] = nums[right] == target ? right : -1;
        return ret;
    }
}

搜索插入位置

        题目解析

在给定的数组中找到 target,如果没有找到,那么找到 target一个插入的位置。

        算法讲解 

· 若是 mid对应的元素小于 target,说明它在 mid 右段,left = mid + 1即可。

· 若是 mid 对应的元素大于等于 target,说明它在 mid 左段,但此时的 mid 就是 target或者应该插入的位置,所以 right = mid。

细节:若是 数组的最后一个位置都小于的话,那么应该插入的位置就是的数组最后一位。

        编写代码 

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

  x 的平方根

        题目解析

本题就是求给定数字的平方根,但不能使用内置接口或方法。

        算法讲解 

· 本题看起来并不能使用二分查找。

· 但是我们抓住一点,那就是 x 的平方根一定比它本身小,且一定大于等于 0。

· 那么我们就得出了 x 的平方根一定在 0 到 x 中,就在这些数字中寻找。

· 若是 mid的平方小于等于 x,则结果一定在 mid的右边,但此时 mid可能就是答案,所以 left = mid。

· 若是 mid的平方大于 x,则结果一定在 mid 的左边,所以 right = mid - 1。

        编写代码 

class Solution {
    public int mySqrt(int x) {
        if (x <= 1) return x;
        long left = 0, right = x;
        while (left < right) {
            long mid = left + (right - left + 1) / 2;
            if (mid * mid <= x) left = mid;
            else right = mid - 1;
        }
        return (int)left;
    }
}

好了,以上就是今天内容的全部讲解,如果有不懂的地方,随时私聊😘

我们下半部分见😁

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值