题目地址(34. 在排序数组中查找元素的第一个和最后一个位置)

https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/

题目描述

  1. 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
  2. 如果数组中不存在目标值 target,返回 [-1, -1]。
  3. 进阶:
  4. 你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
  5. 示例 1
  6. 输入:nums = [5,7,7,8,8,10], target = 8
  7. 输出:[3,4]
  8. 示例 2
  9. 输入:nums = [5,7,7,8,8,10], target = 6
  10. 输出:[-1,-1]
  11. 示例 3
  12. 输入:nums = [], target = 0
  13. 输出:[-1,-1]
  14. 提示:
  15. 0 <= nums.length <= 105
  16. -109 <= nums[i] <= 109
  17. nums 是一个非递减数组
  18. -109 <= target <= 109

前置知识

  • 二分查找

公司

  • 暂无

思路

先把取得边界的情况分为三种

  1. t在边界的左边或者右边
  2. t在边界中间 但是并没有在数组中
  3. t在数组中

针对这3种情况 需要求出数组的左边界和右边界 因为我比较菜 所以将左右边界分开求

关键点


代码

  • 语言支持:Java

Java Code:

  1. class Solution {
  2. public int[] searchRange(int[] nums, int target) {
  3. int leftBorder = getLeftBorder(nums,target);//调用方法 返回左右边界的值
  4. int rightBorder = getRightBorder(nums,target);
  5. //情况一 左右边界的值都是初始化的值 并没有在区间内 如果有其中一个数字大于边界 那么他的其中一个边界值将未定义
  6. if(leftBorder==-2||rightBorder==-2){
  7. return new int[]{-1,-1};
  8. }
  9. //情况三 左右边界中有值
  10. if(rightBorder - leftBorder >1){
  11. return new int[]{leftBorder+1,rightBorder-1};
  12. }
  13. //情况二 在区间内 但是并无值
  14. return new int[]{-1,-1};
  15. }
  16. public int getRightBorder(int[] nums , int target){
  17. int begin = 0, end = nums.length - 1, rightBorder = -2; //初始化未标记的值
  18. while (begin <= end) {
  19. int mid = (begin + end) / 2;
  20. if (nums[mid] > target) {
  21. end = mid - 1;// target 在左区间,所以[left, middle - 1]
  22. } else {// 当nums[middle] == target的时候,更新left,这样才能得到target的右边界
  23. begin = mid + 1;
  24. rightBorder = begin;
  25. }
  26. }
  27. return rightBorder;
  28. }
  29. public int getLeftBorder(int[] nums , int target){
  30. int begin = 0, end = nums.length - 1, leftBorder = -2;
  31. while (begin <= end) {
  32. int mid = (begin + end) / 2;
  33. if (nums[mid] >= target) {// 寻找左边界,就要在nums[middle] == target的时候更新right
  34. end = mid - 1;
  35. leftBorder = end;
  36. } else {
  37. begin = mid + 1;
  38. }
  39. }
  40. return leftBorder;
  41. }
  42. }

复杂度分析

令 n 为数组长度。

  • 时间复杂度:34. 在排序数组中查找元素的第一个和最后一个位置 - 图1#card=math&code=O%28logn%29&id=SbDil)
  • 空间复杂度:34. 在排序数组中查找元素的第一个和最后一个位置 - 图2#card=math&code=O%28n%29&id=zS0vO)