0%

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

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。你的算法时间复杂度必须是 O(log n) 级别。如果数组中不存在目标值,返回 [-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]

解法:递归分治

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
object BinarySearchRange {
def main(args: Array[String]): Unit = {
println(util.Arrays.toString(searchRange(Array(1, 2, 3, 3, 3, 4, 5), 3)))
println(util.Arrays.toString(searchRange(Array(3, 4, 5), 3)))
println(util.Arrays.toString(searchRange(Array(1, 2, 3, 3, 3, 4, 5), 3)))
println(util.Arrays.toString(searchRange(Array(1, 2, 3, 4, 5), 3)))
println(util.Arrays.toString(searchRange(Array(1, 2, 3, 4, 5), 1)))
println(util.Arrays.toString(searchRange(Array(1, 2, 3, 4, 5), 5)))
println(util.Arrays.toString(searchRange(Array(1, 2), 1)))
println(util.Arrays.toString(searchRange(Array(1, 2), 2)))
println(util.Arrays.toString(searchRange(Array(1, 1, 1, 1, 1, 1, 2, 3, 4, 4, 5, 5, 5, 6, 7, 8, 8, 8, 8), 8)))
println(util.Arrays.toString(searchRange(Array(8, 8, 8, 8), 8)))
}

def searchRange(nums: Array[Int], target: Int): Array[Int] = {
search(nums, 0, target)
}

def search(nums: Array[Int], index: Int, target: Int): Array[Int] = {
if (nums.length == 0) return Array(-1, -1)
if (nums.length == 1 && nums(0) == target) 0 else -1

var l = 0
var r = nums.length - 1

val list = new Array[Int](2)

while (l <= r) {
val m = (l + r) / 2
if (nums(m) > target) {
r = m - 1
} else if (nums(m) < target) {
l = m + 1
} else {
list(0) = m + index
list(1) = m + index
val left = search(nums.splitAt(m)._1, 0, target)
val right = search(nums.splitAt(m + 1)._2, m + index + 1, target)

if (left(0) != -1) {
list(0) = Math.min(left(0), list(0))
}

if (right(0) != -1) {
list(1) = Math.max(right(1), list(1))
}

return list
}
}

Array(-1, -1)
}
}