【LeetCode-中等题】34. 在排序数组中查找元素的第一个和最后一个位置

文章目录

题目

方法一:二分查找(先找到mid,在根据mid确定左右区间)

  1. 第一步先找到target所在的位置mid
  2. 在根据mid 在数组左右分两个while循环找左右区间,一旦numsmid != target,就返回mid值
  3. 最后查找位置会停在区间外的一个位置,需要矫正回来
java 复制代码
// 方法一 :二分法找目标元素的位置,然后在目标元素的位置的左右找左右区间
    public int[] searchRange(int[] nums, int target) {
        if(nums.length == 0) return new int[]{-1,-1};
        int mid = search( nums,  target);//二分法找target位置
        if(mid == -1) return new int[]{-1,-1};//若没有  直接返回 - 1  - 1
        int m = mid;
        while(m < nums.length){//根据mid 去找右区间最大下标
                if(nums[m] != target) break;
                 m ++;
        }
        int n = mid;
        while(n >=0){//根据mid 去找左区间最小下标
                if(nums[n] != target) break;
                   n--;
        }
        return new int[]{n+1,m-1};//最终m其实是在右区间后面一个位置停止的  m需要-1  同理最终实是在左区间前面一个位置停止的,n需要+1
    }
    //二分法找目标元素  目标元素不存在返回 - 1
    public int search(int[] nums, int target){
        int left = 0 ;
        int right = nums.length - 1 ;
       while(left <= right){
        int mid = (right - left)/2 + left;
        if(nums[mid] == target) return mid;
        if(nums[mid] > target) right = mid -1;
        if(nums[mid] < target) left = mid +1;
       }
    return -1;
    }

方法二:分两次二分查找,一次用于找左区间,一次用于找右区间

一定要结合画图来理解

java 复制代码
// 方法二 :二分法来去寻找左右边界
    public int[] searchRange(int[] nums, int target) {
        if(nums.length == 0) return new int[]{-1,-1};
        int left = leftjoin(nums,target);
        int right = rightjoin(nums,target);
          // 情况一
        if (left == -2 || right == -2) return new int[]{-1, -1};
        // 情况三
        if (right - left > 1) return new int[]{left + 1, right - 1};
        // 情况二
        return new int[]{-1, -1};

}

    //寻找左边界
    public int leftjoin(int[] nums, int target){
        int left = 0;
        int right = nums.length -1;
        int leftjoin = -2;//记录左边界的赋值情况
        while(left <= right){
            int mid = left + (right -left);
            if(nums[mid] >= target){
                right = mid -1;
                leftjoin = right;
            }else {
                left = mid + 1;
            }
        }
        return leftjoin;
    }
   //寻找右边界
    public int rightjoin(int[] nums, int target){
        int left = 0;
        int right = nums.length -1;
        int rightjoin = -2;//记录左边界的赋值情况
        while(left <= right){
            int mid = left + (right -left);
            if(nums[mid] > target){
                   right = mid -1;
            }else {
             left = mid + 1;
             rightjoin = left;
            }
        }
        return rightjoin;
    }

参考题解:34. 在排序数组中查找元素的第一个和最后一个位置

相关推荐
倒头就睡的小比特5 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼5 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
m0_547486665 天前
《数据结构教程》全套 PPT课件2026
数据结构
旖旎夜光5 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark5 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her15 天前
并查集-听课笔记
笔记·算法·并查集
码流子5 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven5 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark5 天前
从算法设计模式看编程思维的抽象能力4
算法