二分查找_704_35_278_374_34_702

LeetCode_704原题链接:https://leetcode-cn.com/problems/binary-search/

题目描述:

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

代码Demo:

复制代码
public class Search {
    // 二分查找算法,取中间的值进行比较
    public static int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] == target) {
                return mid;
            } else if(nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] nums = {-1, 0, 3, 5, 9, 12};
        int target = 9;
        System.out.println(search(nums, target));
    }
}
复制代码

LeetCode_35原题链接:https://leetcode-cn.com/problems/search-insert-position/

题目描述:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

代码Demo:

复制代码
public static int searchInsert(int[] nums, int target) {
    int i = 0;
    int j = nums.length - 1;
    while (i <= j) {
        int mid = i + (j - i) / 2;
        if (nums[mid] == target) {
            return mid;
        } else if (nums[mid] > target) {
            j = mid - 1;
        } else {
            i = mid + 1;
        }
    }
    return i; // nums中不存在target值时返回此时i值
}
复制代码

LeetCode_278原题链接:https://leetcode-cn.com/problems/first-bad-version/

题目描述:

  假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。

  由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

  可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。

代码Demo:

复制代码
 public int firstBadVersion(int n) {
    int i = 1;
    int j = n;
    while(i <= j) {
        int mid = i + (j - i) / 2;
        if (isBadVersion(mid)) { // 当前为错误版本号,则往前推
            j = mid - 1;
        } else { 
            i = mid + 1;
        }
    }
    return i; 
}
复制代码

LeetCode_374原题链接:https://leetcode-cn.com/problems/guess-number-higher-or-lower/

题目描述:

  • 每轮游戏,我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。
  • 如果你猜错了,我会告诉你,你猜测的数字比我选出的数字是大了还是小了。

可以通过调用一个预先定义好的接口 int guess(int num) 来获取猜测结果,返回值一共有 3 种可能的情况(-11 或 0):

-1:我选出的数字比你猜的数字小 pick < num

1:我选出的数字比你猜的数字大 pick > num

0:我选出的数字和你猜的数字一样。恭喜!你猜对了!pick == num

代码Demo:

复制代码
public int guessNumber(int n) {
    int low = 1;
    int high = n;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        int res = guess(mid);
        if (res == 0)
            return mid;
        else if (res < 0)
            high = mid - 1;
        else
            low = mid + 1;
    }
    return -1;
}
复制代码

LeetCode_34原题链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/

题目描述:

  给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

  如果数组中不存在目标值 target,返回 [-1, -1]。

代码Demo:

复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int i = searchBinaryNum(nums, target); // 二分法取第一个 target 值
        int j = searchBinaryNum(nums, target + 1); // 二分法取第一个target + 1值,最后结果索引-1 即为最后一个 target 值
        if(i == nums.length || nums[i] != target) {
            return new int[]{-1, -1};
        }
        return new int[]{i, j-1}; // 注意返回的是 j - 1
    }

    public int searchBinaryNum(int[] nums, int target) {
        int i = 0;
        int j = nums.length - 1;
        while(i <= j) {
           int mid = i + (j - i) / 2;
           if (nums[mid] >= target) {
               j = mid - 1;
           } else {
               i = mid + 1;
           }
        }
        return i;
    }
}
复制代码

 LeetCode_702原题链接:https://leetcode-cn.com/problems/search-in-a-sorted-array-of-unknown-size/

 题目描述:

  给定一个升序整数数组nums,写一个函数搜索 nums数组中的数字 target。

  如果 target 存在,返回它的下标,否则返回 -1。

       注意,这个数组的大小是未知的。(特殊地方)

  你只可以通过 ArrayReader 接口访问这个数组,ArrayReader.get(k) 返回数组中第 k 个元素(下标从 0 开始)。

  你可以认为数组中所有的整数都小于 10000。

  如果你访问数组越界,ArrayReader.get 会返回 2147483647。

代码Demo:

复制代码
class Solution {
    public int search(ArrayReader reader, int target) {
        if (target >= 10000 || target <= -10000) {  // 初始化判断target值
            return -1;
        }
        int left = 0;
        int right = 1;
        while (target > ArrayReader.get(right)) {  // 预处理确定边界值,如果不进行处理,直接使用Integer.MAX作为right值,进行二分操作效率低。
            left = right;
            right = right * 2;
        }
        int mid;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (ArrayReader.get(mid) < target) {
                left = mid + 1;
            } else if (ArrayReader.get(mid) > target) {
                right = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
}
复制代码
posted @   2022年总冠军gogogo  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示