leetcode 之二分查找(Java实现)(1)

二分查找(Java实现)(1)

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

题目描述:

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

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

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

复制代码
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

复制代码
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

复制代码
输入:nums = [], target = 0
输出:[-1,-1]

提示:

  • 0 <= nums.length <= 1e5
  • -1e9 <= nums[i] <= 1e9
  • nums 是一个非递减数组
  • -1e9 <= target <= 1e9

解题思路:

首先,我们根据题意,可以将target分为三种情况:

  • 情况一、 target不在数组范围内

  • 情况二、target在数组范围内,但是数组中没有这个值

  • 情况三、target在数组中

使用二分的条件

  • 数组有序
  • 要求的结果单一

该问题符合有序的特征,但是条件准确来说有两个,即左边界和右边界。

此时,我们可以将问题拆分开来看,即先求左边界,再求右边界。

  1. 对于左边界,我们是为了求数组中,不小于target的值的最小位置。
  2. 对于右边界,我们是为了求数组中,不大于target的值的最大位置。

我们可以将这两个问题,每一个单独看作要求的结果,符合二分使用条件

分开来求。

我们使用全闭区间,对于左边界而言,我们当 arr[mid] >= target的时候,r = mid - 1。这样,最终求得的结果就是符合条件的位置 - 1.

同理,对于有边界而言,是符合条件的位置 + 1

因此 if(r - l > 1) return new int[]{l + 1, r - 1};返回的便是最终结果。其余两种情况分别为无解。

代码

java 复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int n = nums.length;
        int l = get_left(nums, target, n);
        int r = get_right(nums, target, n);
        if(l == -2 || r == -2) return new int[]{-1, -1};
        if(r - l > 1) return new int[]{l + 1, r - 1};
        return new int[]{-1, -1};
    }

    public static int get_right(int nums[], int target, int n) {
        int l = 0, r = n - 1;
        int idx = -2;
        while( l <= r) {
            int mid = (l + r) / 2;
            if(nums[mid] <= target) {
                l = mid + 1;
                idx = l;
            } else {
                r = mid - 1;
            }
        }
        return idx;
    }

    public static int get_left(int nums[], int target, int n) {
        int l = 0, r = n - 1;
        int idx = -2;
        while(l <= r) {
            int mid = (l + r) / 2;
            if(nums[mid] >= target) {
                r = mid - 1;
                idx = r;
            }
            else l = mid + 1;
        }
        return idx;
    }

}

704、二分查找

题目描述:

704. 二分查找

已解答

简单

相关标签

相关企业

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

示例 1:

复制代码
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

复制代码
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

题解:

本题,可以使用二分,同时,我们使用全开区间进行求解,

对于nums[mid] > target的,r = mid - 1。

对于nums[mid] < target的,l = mid + 1;

相同返回结果。

然后我们需要考虑到会有数组过于小,导致没有进循环的情况,返回结果使用一个三目运算符判断就是最终结果了。

代码:

java 复制代码
class Solution {

    public int search(int[] nums, int target) {
        int l = 0; int r = nums.length - 1;
        while( l < r) {
            int mid = (l + r) / 2;
            if(nums[mid] > target) r = mid - 1;
            else if(nums[mid] < target) l = mid + 1;
            else return mid;
        }
        return nums[l] == target ? l : -1;
    }
}
相关推荐
机器学习之心29 分钟前
机器学习用于算法交易(Matlab实现)
算法·机器学习·matlab
AL流云。30 分钟前
【优选算法】C++滑动窗口
数据结构·c++·算法
qq_429879672 小时前
省略号和可变参数模板
开发语言·c++·算法
飞川撸码3 小时前
【LeetCode 热题100】网格路径类 DP 系列题:不同路径 & 最小路径和(力扣62 / 64 )(Go语言版)
算法·leetcode·golang·动态规划
Neil今天也要学习3 小时前
永磁同步电机参数辨识算法--IPMSM拓展卡尔曼滤波全参数辨识
单片机·嵌入式硬件·算法
yzx9910134 小时前
基于 Q-Learning 算法和 CNN 的强化学习实现方案
人工智能·算法·cnn
亮亮爱刷题4 小时前
算法练习-回溯
算法
眼镜哥(with glasses)5 小时前
蓝桥杯 国赛2024python(b组)题目(1-3)
数据结构·算法·蓝桥杯
int型码农9 小时前
数据结构第八章(一) 插入排序
c语言·数据结构·算法·排序算法·希尔排序
UFIT9 小时前
NoSQL之redis哨兵
java·前端·算法