力扣 查找元素的位置

二分查找经典例题。

题目

要是只是从数组中用二分查找对应的元素,套一下模板一下就可以得出了,然后这题就在于其中会有多个目标元素,要用不同的方式在找到第一个元素时再做偏移。

时间复杂度:O(log n),空间复杂度:O(1)。

java 复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int left = 0;
    int right = nums.length - 1;
    int first = -1;
    int last = -1;
    // 找第一个等于target的位置
    while (left <= right) {
      int middle = (left + right) / 2;
      if (nums[middle] == target) {
        first = middle;
        right = middle - 1; //找到后继续往左,直到找到第一个等于target的位置
      } else if (nums[middle] > target) {
        right = middle - 1;
      } else {
        left = middle + 1;
      }
    }

    // 最后一个等于target的位置
    left = 0;
    right = nums.length - 1;
    while (left <= right) {
      int middle = (left + right) / 2;
      if (nums[middle] == target) {
        last = middle;
        left = middle + 1; //找到后继续往右,直到找到最后一个等于target的位置
      } else if (nums[middle] > target) {
        right = middle - 1;
      } else {
        left = middle + 1;
      }
    }

    return new int[]{first, last};
    }
}

接着也可以套常见的两种二分模板。

一种是将区间[l,r]划分成[l,mid]和[mid+1,r]时,其更新操作是r=mid或者l=mid+1,计算mid时不需要加1,即mid=(l+r)/2。

java 复制代码
while (l < r)
    {
        int mid = (l + r)/2;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }

一种是将区间[l,r]划分成[l,mid−1]和[mid,r]时,其更新操作是r=mid−1或者l=mid,此时为了防止不断循环,计算mid时需要加1,即mid=(l+r+1)/2。

java 复制代码
 while (l < r)
    {
        int mid = ( l + r + 1 ) /2;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }

然后用两种不同的二分查找方式即可以找到数组中目标元素的第一个和最后一个位置了。

时间复杂度:O(log n),空间复杂度:O(1)。

java 复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        if(nums.length == 0) return new int[]{-1,-1};
    
        int low = 0, r = nums.length - 1; 
        while( l < r)			       
        {
            int mid = (l + r )/2;
            if(nums[mid] >= target) r = mid;
            else l = mid + 1;
        }
        if( nums[r] != target) return new int[]{-1,-1}; 
        int L = r;
        l = 0; r = nums.length - 1;    
        while( l < r)			        
        {
            int mid = (l + r +1)/2;
            if(nums[mid] <= target ) l = mid;
            else r = mid - 1;
        }
        return new int[]{L,r};
    }
}
相关推荐
StickToForever3 小时前
第4章 信息系统架构(五)
经验分享·笔记·学习·职场和发展
南山十一少3 小时前
Spring Security+JWT+Redis实现项目级前后端分离认证授权
java·spring·bootstrap
427724004 小时前
IDEA使用git不提示账号密码登录,而是输入token问题解决
java·git·intellij-idea
chengooooooo5 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
李长渊哦5 小时前
常用的 JVM 参数:配置与优化指南
java·jvm
计算机小白一个5 小时前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^5 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
欧了1117 小时前
洛谷P9240 [蓝桥杯 2023 省 B] 冶炼金属
职场和发展·蓝桥杯·洛谷·蓝桥杯大学b组c语言
大数据追光猿7 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!7 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode