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

文章目录

题目

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

  1. 第一步先找到target所在的位置mid
  2. 在根据mid 在数组左右分两个while循环找左右区间,一旦nums[mid] != 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. 在排序数组中查找元素的第一个和最后一个位置

相关推荐
雾里看山28 分钟前
顺序表VS单链表VS带头双向循环链表
数据结构·链表
大千AI助手2 小时前
DTW模版匹配:弹性对齐的时间序列相似度度量算法
人工智能·算法·机器学习·数据挖掘·模版匹配·dtw模版匹配
好好研究3 小时前
学习栈和队列的插入和删除操作
数据结构·学习
YuTaoShao4 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展
生态遥感监测笔记4 小时前
GEE利用已有土地利用数据选取样本点并进行分类
人工智能·算法·机器学习·分类·数据挖掘
Tony沈哲5 小时前
macOS 上为 Compose Desktop 构建跨架构图像处理 dylib:OpenCV + libraw + libheif 实践指南
opencv·算法
刘海东刘海东5 小时前
结构型智能科技的关键可行性——信息型智能向结构型智能的转变(修改提纲)
人工智能·算法·机器学习
pumpkin845146 小时前
Rust 调用 C 函数的 FFI
c语言·算法·rust
挺菜的6 小时前
【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
java·数据结构·算法