[LeetCode] 34. Find First and Last Position of Elements in Sorted Array(在有序数组中寻找某个元素第一次和最后一次出现的位置)
-
Difficulty: Medium
-
Related Topics: Array, Binary Search
-
Link: https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/
Description
Given an array of integers nums
sorted in ascending order, find the starting and ending position of a given target
value.
给定一个升序排序整数数组 nums
,找给定值 target
的第一次和最后一次出现的位置。
If target
is not found in the array, return [-1, -1]
.
如果 target
未找到,返回 [-1, -1]
。
Follow up
Could you write an algorithm with O(log n)
runtime complexity?
你能在 O(log n)
时间复杂度下完成吗?
Examples
Example 1
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
Example 3
Input: nums = [], target = 0
Output: [-1,-1]
Constraints
0 <= nums.length <= 1e5
-1e9 <= nums[i] <= 1e9
nums
is a non-decreasing array.-1e9 <= target <= 1e9
Solution
这题实际上是两个子问题的缝合:寻找一个数在数组里的左边界和右边界。这是二分查找的变式,具体解法可以参考这篇博客:详解二分查找算法 - murphy_gb - 博客园 (cnblogs.com),代码如下:
class Solution {
fun searchRange(nums: IntArray, target: Int): IntArray {
return intArrayOf(leftBound(nums, target), rightBound(nums, target))
}
private fun leftBound(nums: IntArray, target: Int): Int {
if (nums.isEmpty()) {
return -1
}
var left = 0
var right = nums.size
while (left < right) {
val mid = left + (right - left) / 2
if (nums[mid] < target) {
left = mid + 1
} else {
right = mid
}
}
if (left == nums.size) {
return -1
}
return if (nums[left] == target) {
left
} else {
-1
}
}
private fun rightBound(nums: IntArray, target: Int): Int {
if (nums.isEmpty()) {
return -1
}
var left = 0
var right = nums.size
while (left < right) {
val mid = left + (right - left) / 2
if (nums[mid] <= target) {
left = mid + 1
} else {
right = mid
}
}
if (left == 0) {
return -1
}
return if (nums[left - 1] == target) {
left - 1
} else {
-1
}
}
}