LeetCode 0034.在排序数组中查找元素的第一个和最后一个位置【Go】

简介: LeetCode 0034.在排序数组中查找元素的第一个和最后一个位置【Go】

在排序数组中查找元素的第一个和最后一个位置

leetcode34. 在排序数组中查找元素的第一个和最后一个位置

题目描述

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

输入:nums = [], target = 0
输出:[-1,-1]

思路

题目要求

  • 在升序数组中查找目标元素的索引区间
  • 若未找到目标元素,则返回[-1, -1]

在升序数组中查找目标元素,考虑使用二分查找法。但需要对二分法做出适当改变。

由于目标元素在数组中可能重复,所以使用二分法时需要在找到目标元素后,继续再向左和向右寻找左边界和右边界。

由于数组是升序的,所以重复元素在数组中也一定是连续的。

寻找左边界就是寻找第一个大于等于目标元素的元素的索引,寻找有边界就是寻找第一个大于目标元素的元素的索引。

注意

  • 寻找左边界:当找到目标元素后,判断当前元素nums[mid],若是mid=0nums[mid-1] < target,则无需继续向左寻找,左边界就是当前元素的索引mid。反之,执行right = mid - 1,继续左区间中寻找左边界。
  • 寻找右边界:当找到目标元素后,判断当前元素nums[mid],若是mid=len(nums)-1nums[mid+1] > target,则无需继续向左寻找,左边界就是当前元素的索引mid。反之,执行left = mid + 1,继续右区间中寻找右边界。

代码

Go

// 找左边界
func getLeftBorder(nums []int, target int) int {
  left, right := 0, len(nums)-1
  for left <= right {
    mid := left + (right-left)/2
    if nums[mid] < target {
      left = mid + 1
    } else if nums[mid] > target {
      right = mid - 1
    } else if nums[mid] == target && (mid == 0 || nums[mid-1] < target) {
      return mid
    } else {
      right = mid - 1
    }
  }
  return -1
}
//找右边界
func getRightBorder(nums []int, target int) int {
  left, right := 0, len(nums)-1
  for left <= right {
    mid := left + (right-left)/2
    if nums[mid] < target {
      left = mid + 1
    } else if nums[mid] > target {
      right = mid - 1
    } else if nums[mid] == target && (mid == len(nums)-1 || nums[mid+1] > target) {
      return mid
    } else {
      left = mid + 1
    }
  }
  return -1
}
func searchRange(nums []int, target int) []int {
  leftBorder := getLeftBorder(nums, target)
  rightBorder := getRightBorder(nums, target)
  return []int{leftBorder, rightBorder}
}

Link

GitHub

目录
相关文章
|
2月前
|
算法
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
|
4天前
|
编译器 Go 索引
Go to Learn Go之数组
Go to Learn Go之数组
12 0
|
2月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
2月前
|
算法
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
6天前
|
编译器 Go 索引
Go数组、多维数组和切片(动态数组),及常用函数len(),cap(),copy(),append()在切片中的使用
本文介绍了Go语言中数组、多维数组和切片(动态数组)的基本概念和操作,包括数组的定义、初始化、访问,多维数组的定义和访问,以及切片的创建、使用和扩容。同时,还讲解了切片中常用的函数len()、cap()、copy()和append()的使用方法。
|
2月前
|
存储 编译器 Go
|
2月前
|
存储 Go 数据处理
C 数组和 Go 切片的区别详解
【8月更文挑战第31天】
30 0
|
2月前
|
人工智能 编译器 Go
Go从入门到放弃之数组、切片
Go从入门到放弃之数组、切片
|
2月前
|
算法 安全 Go
|
5天前
|
Go
Go 语言循环语句
在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。
13 1
下一篇
无影云桌面