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;
    }
}
相关推荐
在西湖雾雨中起舞19 分钟前
P9748 [CSP-J 2023] 小苹果
算法
海海不掉头发27 分钟前
【 算法设计与分析-回顾算法知识点】福建师范大学数学与计算机科学学院 2006 — 2007学年第二学期考试 A 卷
算法·期末复习
Cosmoshhhyyy2 小时前
LeetCode:3297. 统计重新排列后包含另一个字符串的子字符串数目 I(滑动窗口 Java)
java·leetcode
太阳照常升起3662 小时前
机试准备第一天
算法
Non importa2 小时前
【初阶数据结构】线性表之单链表
数据结构·考研·算法·链表·github·学习方法
fanstuck2 小时前
如何快速准备数学建模?
算法·数学建模·数据挖掘
Static_Xiao2 小时前
C语言导航 7.1函数的概念与定义
c语言·数据结构·算法
萌の鱼2 小时前
leetcode 53. 最大子数组和
数据结构·c++·算法·leetcode
水水阿水水2 小时前
第二章:面向对象之封装(一)
开发语言·c++·算法
圆圆滚滚小企鹅。3 小时前
刷题记录 回溯算法-5:17.电话号码的字母组合
数据结构·python·算法·leetcode