当前位置: 首页 > article >正文

力扣 查找元素的位置

二分查找经典例题。

题目

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

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

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。 

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。

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

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

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

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};
    }
}


http://www.kler.cn/a/506151.html

相关文章:

  • Jmeter 简单使用、生成测试报告(一)
  • px、em 和 rem 的区别:深入理解 CSS 中的单位
  • Freeswitch使用media_bug能力实现回铃音检测
  • 【WEB】网络传输中的信息安全 - 加密、签名、数字证书与HTTPS
  • Python的秘密基地--[章节11] Python 性能优化与多线程编程
  • “AI 自动化效能评估系统:开启企业高效发展新征程
  • # [游戏开发] Unity中的碰撞与触发器实现:从基础到应用
  • usb通过hdc连接鸿蒙next的常用指令
  • 判断192.168.1.0/24网络中,当前在线的ip有哪些
  • 文件上传生成pdf
  • 混币器是什么,波卡跨链交易平台
  • 河道流量在线自动监测系统:实时监控水流,保障河道管理安全
  • 阿里云轻量应用服务器全新升级,通用型实例峰值带宽高达200Mbps
  • 基于Oracle与PyQt6的电子病历多模态大模型图形化查询系统编程构建
  • 使用Go语言中的Buffer实现高性能处理字节和字符串
  • hashcat破解密码时出现signature unmatched error或者no hashes loaded的一种可能的原因
  • IP归属地为什么和定位不一致?原因解析
  • linux入门一
  • tomcat状态一直是Exited (1)
  • 【一个按钮一个LED】用STM32F030单片机实现苹果充电器的定时装置
  • Coconut:基于连续潜在空间推理,提升大语言模型推理能力的新方法
  • Dataset之COCO数据集:COCO数据集
  • jenkins-node节点配置
  • vue3+elementPlus之后台管理系统(从0到1)(day1)
  • leetcode:205. 同构字符串(python3解法)
  • Scala语言的多线程编程